I'm creating an Android application and I needed to create a Drawable with a gradient background and text inside, but for some reason I don't have a gradient, and the entire background is filled with solid color
Class code:
class TestDrawable(textSize: Int = 16) : Drawable() {
private val rect = RectF()
private val paint = Paint(Paint.ANTI_ALIAS_FLAG)
private val textPaint = TextPaint(Paint.ANTI_ALIAS_FLAG)
private val textWidth: Int
private val text: String
private var backgroundGradient: LinearGradient = LinearGradient(
0f, 0f, intrinsicWidth.toFloat(), 0f,
intArrayOf(-0xb73320, -0xafa523, -0x41bf40, -0x457d5),
floatArrayOf(0.06f, 0.34f, 0.73f, 1f),
Shader.TileMode.CLAMP
)
override fun draw(canvas: Canvas) {
rect.set(bounds)
canvas.drawRoundRect(rect,
AndroidUtilities.dp(2f).toFloat(),
AndroidUtilities.dp(2f).toFloat(), paint)
canvas.drawText(
text,
rect.left AndroidUtilities.dp(5f),
rect.top AndroidUtilities.dp(12f),
textPaint
)
}
override fun getIntrinsicWidth(): Int {
return textWidth AndroidUtilities.dp((5 * 2).toFloat())
}
override fun getIntrinsicHeight(): Int {
return AndroidUtilities.dp(16f)
}
init {
textPaint.textSize = AndroidUtilities.dp(textSize.toFloat()).toFloat()
textPaint.typeface = AndroidUtilities.getTypeface("fonts/rmedium.ttf")
textPaint.color = -0x1000000
//paint.style = Paint.Style.FILL
paint.color = -0x1
paint.shader = backgroundGradient
backgroundGradient.setLocalMatrix(Matrix())
text = "plus".uppercase()
textWidth = ceil(textPaint.measureText(text).toDouble()).toInt()
}
}
CodePudding user response:
You're initialising backgroundGradient
when you declare the variable, and that sets the gradient width with a call to getIntrinsicWidth
, which itself relies on textWidth
having been initialised. But that initialisation happens in the init
block, which is below backgroundGradient
, so it hasn't run yet.
I haven't tested it but I'm guessing textWidth
is still zero (they behave like Java objects/primitives in this situation) so you're getting a very tiny gradient and the rest of your background is just the end colour. Try initialising your gradient in init
, after textWidth
has been set