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?
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()
}