class DashboardView @JvmOverloads constructor(
context: Context, @Nullable attrs: AttributeSet? = null,
defStyleAttr: Int = 0,
defStyleRes: Int = 0
) : View(context, attrs, defStyleAttr, defStyleRes) {
private val paint: Paint = Paint(Paint.ANTI_ALIAS_FLAG)
private val path: Path = Path()
private val bounds: RectF = RectF()
private val radius: Float = dp2px(150F)
private val openAngle: Float = 120F
private val startAngle: Float = 90 + openAngle / 2
private val sweepAngle: Float = 360 - openAngle
private val pathMeasure: PathMeasure = PathMeasure()
private val markLength: Float = dp2px(120F)
private val markCount: Int = 9
private val markIndex: Int = 6
private lateinit var pathDashPathEffect: PathDashPathEffect
private val dashPath: Path = Path()
init {
paint.style = Paint.Style.STROKE
paint.strokeWidth = dp2px(3F)
dashPath.addRect(RectF(0F, 0F, dp2px(3F), dp2px(9F)), Path.Direction.CW)
}
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
path.reset()
bounds.set(width / 2 - radius, height / 2 - radius, width / 2 + radius, height / 2 + radius)
path.addArc(bounds, startAngle, sweepAngle)
pathMeasure.setPath(path, false)
val length = pathMeasure.length
pathDashPathEffect = PathDashPathEffect(
dashPath,
(length - dp2px(3F)) / (markCount - 1),
0F,
PathDashPathEffect.Style.ROTATE
)
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
canvas.drawPath(path, paint)
paint.pathEffect = pathDashPathEffect
canvas.drawPath(path, paint)
paint.pathEffect = null
canvas.drawLine(
width / 2F,
height / 2F,
(width / 2F + markLength * Math.cos(Math.toRadians((startAngle + sweepAngle / (markCount - 1) * markIndex).toDouble()))).toFloat(),
(height / 2F + markLength * Math.sin(Math.toRadians((startAngle + sweepAngle / (markCount - 1) * markIndex).toDouble()))).toFloat(),
paint
)
}
private fun dp2px(dp: Float) = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dp,
Resources.getSystem().displayMetrics
)
}