Home > Blockchain >  Could somebody explain to me how this custom View code works?
Could somebody explain to me how this custom View code works?

Time:02-02

class DrawingView(context: Context, attributeSet: AttributeSet) : View(context, attributeSet) {
    private lateinit var mDrawPath: FingerPath
    private lateinit var mCanvasBitmap: Bitmap
    private lateinit var mCanvasPaint: Paint
    private lateinit var mDrawPaint: Paint
    private var mBrushSize = 0
    private var color = Color.BLACK
    private lateinit var canvas: Canvas

    init {
        setUpDrawing()
    }

    private fun setUpDrawing() {
        mDrawPaint = Paint()
        mDrawPath = FingerPath(color, mBrushSize.toFloat())
        mDrawPaint.color = color
        mDrawPaint.style = Paint.Style.STROKE
        mDrawPaint.strokeJoin = Paint.Join.ROUND
        mDrawPaint.strokeCap = Paint.Cap.ROUND
        mCanvasPaint = Paint(Paint.DITHER_FLAG)
        mBrushSize = 20

    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        mCanvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888)
        canvas = Canvas(mCanvasBitmap)

    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        canvas.drawBitmap(mCanvasBitmap, 0f, 0f, mDrawPaint)
        if (!mDrawPath.isEmpty) {
            mDrawPaint.strokeWidth = mDrawPath.brushThickness
            mDrawPaint.color = mDrawPath.color
            canvas.drawPath(mDrawPath, mDrawPaint)
        }
    }

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        val touchX = event?.x
        val touchY = event?.y

        when (event?.action) {
            MotionEvent.ACTION_DOWN -> {
                mDrawPath.color = color
                mDrawPath.brushThickness = mBrushSize.toFloat()

                mDrawPath.reset()
                mDrawPath.moveTo(touchX!!, touchY!!)
            }

            MotionEvent.ACTION_MOVE -> {
                mDrawPath.lineTo(touchX!!, touchY!!)

            }

            MotionEvent.ACTION_UP -> {
                mDrawPath = FingerPath(color, mBrushSize.toFloat())
            }
            else -> return false
        }

        invalidate()
        return true
    }

    internal inner class FingerPath(var color: Int, var brushThickness: Float) : Path()
}

So, I'm taking a course about Android Development and the instructor is building a drawing app -- and I can't understand how to code works, because he's not explaining the 'why'; so, he types a lot of code without explaining why he uses that variable or why is he overring those functions; therefore, I don't understand how to code work. Could you help me in understanding how this code work?

CodePudding user response:

class DrawingView(context: Context, attributeSet: AttributeSet) : View(context, attributeSet) {
    private lateinit var mDrawPath: FingerPath
    private lateinit var mCanvasBitmap: Bitmap
    private lateinit var mCanvasPaint: Paint
    private lateinit var mDrawPaint: Paint
    private var mBrushSize = 0
    private var color = Color.BLACK
    private lateinit var canvas: Canvas

    init {
// init block will called first when instance will be created so we
// are calling method setUpDrawing() as it is initialising everything
// that required to draw like color , brush size , brush behaviour
// (round , stroke etc .. ) . in simple manner , we can say painter is
// collecting all required tools before starting to paint

        setUpDrawing() 
    }

    private fun setUpDrawing() {
        mDrawPaint = Paint()
        mDrawPath = FingerPath(color, mBrushSize.toFloat())
        mDrawPaint.color = color
        mDrawPaint.style = Paint.Style.STROKE
        mDrawPaint.strokeJoin = Paint.Join.ROUND
        mDrawPaint.strokeCap = Paint.Cap.ROUND
        mCanvasPaint = Paint(Paint.DITHER_FLAG)
        mBrushSize = 20

    }

 // this method is going to be called by system when size is going to be
// changed so we are here creating blank board on which we are going to
// draw
    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        mCanvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888)
        canvas = Canvas(mCanvasBitmap)

    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        canvas.drawBitmap(mCanvasBitmap, 0f, 0f, mDrawPaint)
        if (!mDrawPath.isEmpty) {
            mDrawPaint.strokeWidth = mDrawPath.brushThickness
            mDrawPaint.color = mDrawPath.color
            canvas.drawPath(mDrawPath, mDrawPaint) // drawing path on canvas
        }
    }

// this method will be called by system when user is going to touch screen
    override fun onTouchEvent(event: MotionEvent?): Boolean {
        val touchX = event?.x
        val touchY = event?.y

        when (event?.action) {
// this event will be fired when user put finger on screen
            MotionEvent.ACTION_DOWN -> { 
                mDrawPath.color = color
                mDrawPath.brushThickness = mBrushSize.toFloat()

                mDrawPath.reset() // reseting path before we set inital point
                mDrawPath.moveTo(touchX!!, touchY!!)// set point from where drawing will be started 
            }

// this event will be fired when user start to move it's fingure . this will be fired continually until user pickup fingure 
            MotionEvent.ACTION_MOVE -> {
                mDrawPath.lineTo(touchX!!, touchY!!)

            }
// this event will be fired when user will pick up fingure from screen
            MotionEvent.ACTION_UP -> {
                mDrawPath = FingerPath(color, mBrushSize.toFloat())
            }
            else -> return false
        }

        invalidate() / /refreshing layout to reflect drawing changes
        return true
    }

    internal inner class FingerPath(var color: Int, var brushThickness: Float) : Path()
}

CodePudding user response:

This code is a custom view class in Android for drawing. The class extends the View class and implements touch event handling to allow a user to draw on the screen.

The class defines instance variables to store the paint, path, bitmap and canvas used for drawing. It also has variables for brush size and color.

In the setUpDrawing method, the paint object for drawing and the path object for tracking the user's touch are set up. In onSizeChanged, the bitmap object is created and its canvas object is initialized. In onDraw, the canvas is drawn on the screen and the path is drawn on the canvas if it's not empty.

The onTouchEvent method handles touch events (DOWN, MOVE, UP) and updates the path accordingly. The FingerPath inner class extends the Path class and contains the color and brush size of the path.

  • Related