Skip to content

Instantly share code, notes, and snippets.

@Miha-x64
Last active June 15, 2022 00:52
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Miha-x64/9511e15f96a2eed33804ad0b390ed9cf to your computer and use it in GitHub Desktop.
Save Miha-x64/9511e15f96a2eed33804ad0b390ed9cf to your computer and use it in GitHub Desktop.
class GradientStrokeDrawable : Drawable() {
var radius: Float = 0f
set(radius) {
if (field != radius) {
check(radius.isFinite() && radius >= 0f)
field = radius
path.rewind()
invalidateSelf()
}
}
var stroke: Float = 0f
set(stroke) {
if (field != stroke) {
check(stroke.isFinite() && stroke >= 0f)
field = stroke
path.rewind()
invalidateSelf()
}
}
var gradient: Pair<IntArray, FloatArray?> = Pair(intArrayOf(Color.TRANSPARENT), null)
set(gradient) {
val (colors, positions) = gradient
check(colors.isNotEmpty())
if (positions != null) {
check(positions.size == colors.size)
check(positions.all { it in 0f..1f })
}
field = gradient
paint.shader = null
invalidateSelf()
}
private val path = Path()
private val paint = Paint(Paint.ANTI_ALIAS_FLAG)
override fun getAlpha(): Int = paint.alpha
override fun setAlpha(alpha: Int) { paint.alpha = alpha }
override fun getColorFilter(): ColorFilter? = paint.colorFilter
override fun setColorFilter(colorFilter: ColorFilter?) { paint.colorFilter = colorFilter }
override fun getOpacity(): Int = PixelFormat.TRANSLUCENT
override fun setBounds(bounds: Rect) {
if (this.bounds.width() != bounds.width() || this.bounds.height() != bounds.height()) {
path.rewind()
paint.shader = null
}
super.setBounds(bounds)
}
override fun draw(canvas: Canvas) {
val (l, t, r, b) = bounds
val w = r - l
val h = b - t
if (path.isEmpty) {
path.buildRRStroke(0f, 0f, w.toFloat(), h.toFloat(), radius, stroke)
}
if (paint.shader == null) {
val (colors, positions) = gradient
paint.shader = LinearGradient(0f, 0f, w.toFloat(), h.toFloat(), colors, positions, Shader.TileMode.MIRROR)
}
canvas.withTranslation(l.toFloat(), t.toFloat()) {
canvas.drawPath(path, paint)
}
}
fun Path.buildRRStroke(left: Float, top: Float, right: Float, bottom: Float, radius: Float, thickness: Float) {
addRoundRect(
left, top, right, bottom,
radius, radius, Path.Direction.CW
)
addRoundRect(
left + thickness, top + thickness, right - thickness, bottom - thickness,
radius - thickness, radius - thickness, Path.Direction.CCW
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment