Skip to content

Commit 86c2748

Browse files
committed
add onTouchEvent()
1 parent 14e7592 commit 86c2748

File tree

3 files changed

+70
-5
lines changed

3 files changed

+70
-5
lines changed

22-minipaint/README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22

33
A simple line drawing app, using a canvas.
44

5-
<!-- <p align="center">
5+
<p align="center">
66
<img src="screenshot.png" style="width:528px;max-width: 100%;">
7-
</p> -->
7+
</p>
88

99
## Features
1010

1111
- creating a custom view for drawing.
1212
- displaying the canvas.
1313
- setting up a paint and a path for drawing.
14-
- drawing following the user's touch.
14+
- drawing following the user's touch with onTouchEvent().
1515

1616
Based on [Drawing on Canvas Objects](https://developer.android.com/codelabs/advanced-android-kotlin-training-canvas#0) by Google Codelabs (2022).
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,91 @@
11
package com.hfad.minipaint
22

33
import android.content.Context
4-
import android.graphics.Bitmap
5-
import android.graphics.Canvas
4+
import android.graphics.*
5+
import android.view.MotionEvent
66
import android.view.View
7+
import android.view.ViewConfiguration
78
import androidx.core.content.res.ResourcesCompat
89

10+
private const val STROKE_WIDTH = 12f
11+
912
class MyCanvasView(context: Context) : View(context) {
1013
private lateinit var extraCanvas: Canvas
1114
private lateinit var extraBitmap: Bitmap
15+
private lateinit var frame: Rect
1216
private val backgroundColor = ResourcesCompat.getColor(resources, R.color.colorBackground, null)
17+
private val drawColor = ResourcesCompat.getColor(resources, R.color.colorPaint, null)
18+
private val paint = Paint().apply {
19+
color = drawColor
20+
isAntiAlias = true
21+
isDither = true
22+
style = Paint.Style.STROKE
23+
strokeJoin = Paint.Join.ROUND
24+
strokeCap = Paint.Cap.ROUND
25+
strokeWidth = STROKE_WIDTH
26+
}
27+
private val touchTolerance = ViewConfiguration.get(context).scaledTouchSlop
1328

1429
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
1530
super.onSizeChanged(w, h, oldw, oldh)
1631
if (::extraBitmap.isInitialized) extraBitmap.recycle() // avoid memory leak
1732
extraBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888)
1833
extraCanvas = Canvas(extraBitmap)
1934
extraCanvas.drawColor(backgroundColor)
35+
// add a rectangular frame
36+
val inset = 40
37+
frame = Rect(inset, inset, w - inset, h - inset)
38+
extraCanvas.drawRect(frame, paint)
2039
}
2140

2241
override fun onDraw(canvas: Canvas) {
2342
super.onDraw(canvas)
2443
canvas.drawBitmap(extraBitmap, 0f, 0f, null)
2544
}
45+
46+
override fun onTouchEvent(event: MotionEvent): Boolean {
47+
motionTouchEventX = event.x
48+
motionTouchEventY = event.y
49+
50+
when (event.action) {
51+
MotionEvent.ACTION_DOWN -> touchStart()
52+
MotionEvent.ACTION_MOVE -> touchMove()
53+
MotionEvent.ACTION_UP -> touchUp()
54+
}
55+
return true
56+
}
57+
58+
private fun touchStart() {
59+
path.reset()
60+
path.moveTo(motionTouchEventX, motionTouchEventY)
61+
currentX = motionTouchEventX
62+
currentY = motionTouchEventY
63+
}
64+
65+
private fun touchMove() {
66+
val dx = Math.abs(motionTouchEventX - currentX)
67+
val dy = Math.abs(motionTouchEventY - currentY)
68+
if (dx >= touchTolerance || dy >= touchTolerance) {
69+
// QuadTo() adds a quadratic bezier from the last point,
70+
// approaching control point (x1,y1), and ending at (x2,y2).
71+
path.quadTo(currentX, currentY, (motionTouchEventX + currentX) / 2, (motionTouchEventY + currentY) / 2)
72+
currentX = motionTouchEventX
73+
currentY = motionTouchEventY
74+
// Draw the path in the extra bitmap to cache it.
75+
extraCanvas.drawPath(path, paint)
76+
}
77+
invalidate()
78+
}
79+
80+
private fun touchUp() {
81+
path.reset()
82+
}
83+
84+
companion object {
85+
private var path = Path()
86+
private var motionTouchEventX = 0f
87+
private var motionTouchEventY = 0f
88+
private var currentX = 0f
89+
private var currentY = 0f
90+
}
2691
}

22-minipaint/screenshot.png

144 KB
Loading

0 commit comments

Comments
 (0)