Thursday, July 9, 2020

android kotlin - Canvas draw line

MainActivity.kt

package com.example.jetpack

import android.graphics.*
import android.os.Bundle
import android.widget.SeekBar
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*


class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        borderWidth.max = 100
        pointX.max = 1500
        pointY.max = 850
        point2X.max = 1500
        point2Y.max = 850

        borderWidth.progress = 20
        pointX.progress = 100
        pointY.progress = 100
        point2X.progress = 600
        point2Y.progress = 500

        updateDrawing()

        setSeekBarChangeListener(borderWidth)
        setSeekBarChangeListener(pointX)
        setSeekBarChangeListener(pointY)
        setSeekBarChangeListener(point2X)
        setSeekBarChangeListener(point2Y)

        radioGroup.setOnCheckedChangeListener { group, checkedId ->
            updateDrawing()
        }
    }


    private fun setSeekBarChangeListener(seekBar: SeekBar){
        seekBar.setOnSeekBarChangeListener(
            object: SeekBar.OnSeekBarChangeListener{
                override fun onProgressChanged(
                    seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
                    updateDrawing()
                }

                override fun onStartTrackingTouch(seekBar: SeekBar?) {
                }

                override fun onStopTrackingTouch(seekBar: SeekBar?) {
                }
            })
    }


    private fun updateDrawing(){
        val cap:Paint.Cap = when(radioGroup.checkedRadioButtonId){
            R.id.square -> Paint.Cap.SQUARE
            R.id.round -> Paint.Cap.ROUND
            R.id.but -> Paint.Cap.BUTT
            else -> Paint.Cap.SQUARE
        }

        val bitmap = drawSingleLine(
            point = Point(pointX.progress,pointY.progress),
            point2 = Point(point2X.progress, point2Y.progress),
            strokeWidth = borderWidth.progress.toFloat(),
            cap = cap
        )
        imageView.setImageBitmap(bitmap)

        textView.text = "( ${pointX.progress} : ${pointY.progress} )"
        textView.append("   ( ${point2X.progress} : ${point2Y.progress} )")
    }
}


// function to draw single line on canvas
fun drawSingleLine(
    point: Point = Point(150,400),
    point2: Point = Point(650, 400),
    strokeWidth : Float = 25F,
    cap : Paint.Cap = Paint.Cap.SQUARE
):Bitmap?{
    val bitmap = Bitmap.createBitmap(
        1500,
        850,
        Bitmap.Config.ARGB_8888
    )

    // canvas for drawing
    val canvas = Canvas(bitmap).apply {
        drawColor(Color.parseColor("#D4AF37"))
    }

    // paint to draw
    val paint = Paint().apply {
        isAntiAlias = true
        color = Color.parseColor("#996515")
        style = Paint.Style.STROKE
        this.strokeWidth = strokeWidth
        strokeCap = cap
    }

    // finally, draw the line on canvas
    canvas.drawLine(
        point.x.toFloat(), // start x
        point.y.toFloat(), // start y
        point2.x.toFloat(), // stop x
        point2.y.toFloat(), // stop y
        paint // paint
    )

    return bitmap
}
activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/constraintLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#E9D66B"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="2dp"
        android:layout_marginEnd="8dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:srcCompat="@tools:sample/avatars" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:text="TextView"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/imageView" />

    <RadioGroup
        android:id="@+id/radioGroup"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/textView">

        <com.google.android.material.radiobutton.MaterialRadioButton
            android:id="@+id/square"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Cap Square" />

        <com.google.android.material.radiobutton.MaterialRadioButton
            android:id="@+id/round"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Round"
            />

        <com.google.android.material.radiobutton.MaterialRadioButton
            android:id="@+id/but"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="But"
            />
    </RadioGroup>

    <SeekBar
        android:id="@+id/borderWidth"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:progressTint="#3F51B5"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/radioGroup" />

    <SeekBar
        android:id="@+id/pointX"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:progressTint="#7BB661"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/borderWidth" />

    <SeekBar
        android:id="@+id/pointY"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:progressTint="#7BB661"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/pointX" />

    <SeekBar
        android:id="@+id/point2X"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:progressTint="#FF5470"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/pointY" />

    <SeekBar
        android:id="@+id/point2Y"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:progressTint="#FF5470"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/point2X" />

</androidx.constraintlayout.widget.ConstraintLayout>