@@ -5,8 +5,6 @@ import android.graphics.ColorFilter
55import android.graphics.Paint
66import android.graphics.Path
77import android.graphics.PixelFormat
8- import android.graphics.PorterDuff
9- import android.graphics.PorterDuffXfermode
108import android.graphics.drawable.Drawable
119
1210class CheckboxDrawable (
@@ -15,42 +13,52 @@ class CheckboxDrawable(
1513 private var isChecked : Boolean ,
1614) : Drawable() {
1715 private val paint = Paint (Paint .ANTI_ALIAS_FLAG )
18- private val path = Path ()
16+ private val strokeForCheckPaint = Paint (Paint .ANTI_ALIAS_FLAG )
17+ private val rectPath = Path ()
18+ private val checkStrokePath = Path ()
19+ private val checkOutlinePath = Path ()
1920
2021 fun update (checked : Boolean ) {
2122 this .isChecked = checked
2223 invalidateSelf()
2324 }
2425
2526 override fun draw (canvas : Canvas ) {
26- val saveCount = canvas.saveLayer(0f , 0f , size.toFloat(), size.toFloat(), null )
27-
2827 paint.color = color
29- paint.style = Paint .Style .FILL
3028
31- // Full square background with transparent checkmark
3229 if (isChecked) {
3330 val cornerRadius = size * 0.15f
34- canvas.drawRoundRect(0f , 0f , size.toFloat(), size.toFloat(), cornerRadius, cornerRadius, paint)
31+ rectPath.reset()
32+ rectPath.addRoundRect(
33+ 0f ,
34+ 0f ,
35+ size.toFloat(),
36+ size.toFloat(),
37+ cornerRadius,
38+ cornerRadius,
39+ Path .Direction .CW ,
40+ )
41+
42+ checkStrokePath.reset()
43+ checkStrokePath.moveTo(size * 0.25f , size * 0.5f )
44+ checkStrokePath.lineTo(size * 0.45f , size * 0.7f )
45+ checkStrokePath.lineTo(size * 0.75f , size * 0.3f )
3546
36- paint.xfermode = PorterDuffXfermode (PorterDuff .Mode .XOR )
37- paint.strokeWidth = size * 0.15f
38- paint.style = Paint .Style .STROKE
39- paint.strokeCap = Paint .Cap .ROUND
40- paint.strokeJoin = Paint .Join .ROUND
47+ strokeForCheckPaint.style = Paint .Style .STROKE
48+ strokeForCheckPaint.strokeWidth = size * 0.15f
49+ strokeForCheckPaint.strokeCap = Paint .Cap .ROUND
50+ strokeForCheckPaint.strokeJoin = Paint .Join .ROUND
51+ checkOutlinePath.reset()
52+ strokeForCheckPaint.getFillPath(checkStrokePath, checkOutlinePath)
4153
42- path.reset()
43- path.moveTo(size * 0.25f , size * 0.5f )
44- path.lineTo(size * 0.45f , size * 0.7f )
45- path.lineTo(size * 0.75f , size * 0.3f )
46- canvas.drawPath(path, paint)
54+ // rectPath minus check outline = filled shape with transparent tick (API 19+).
55+ rectPath.op(checkOutlinePath, Path .Op .DIFFERENCE )
4756
48- paint.xfermode = null
49- canvas.restoreToCount(saveCount )
57+ paint.style = Paint . Style . FILL
58+ canvas.drawPath(rectPath, paint )
5059 return
5160 }
5261
53- // Border only square for unchecked state
5462 paint.style = Paint .Style .STROKE
5563 paint.strokeWidth = size * 0.1f
5664 val margin = paint.strokeWidth / 2f
@@ -64,8 +72,6 @@ class CheckboxDrawable(
6472 cornerRadius,
6573 paint,
6674 )
67-
68- canvas.restoreToCount(saveCount)
6975 }
7076
7177 override fun setAlpha (alpha : Int ) {
0 commit comments