Feri Nagy
01/18/2022, 8:30 AMPainter
to a Drawable
? I know that for the other way there is painterResource()
and rememberDrawablePainter()
in Accompanist, but I have not found anything about the inverse way.Feri Nagy
01/18/2022, 8:40 AMAndroidView
like:
CustomView(title: String, icon: Painter, margin: Dp, modifier: Modifier)
It can handle strings just fine and I can convert Dp
to pixels easily, but I am for now stuck on the Painter->Drawable
.Feri Nagy
01/18/2022, 8:42 AMDrawable
, but that feels a bit weird in a compose world.Antoine Gagnon
01/18/2022, 4:57 PMInt
id?
There’s nothing you can extract from the BitmapPainter/VectorPainter that the painterRessource createsAdam Powell
01/19/2022, 3:20 AMTolriq
01/19/2022, 8:09 AMFeri Nagy
01/19/2022, 10:27 AM@Composable
fun Painter.toDrawable(
density: Density = LocalDensity.current,
layoutDirection: LayoutDirection = LocalLayoutDirection.current
): Drawable = object : Drawable() {
private var alpha = 0xFF
private var colorFilter: ColorFilter? = null
override fun draw(canvas: android.graphics.Canvas) {
val scope = CanvasDrawScope()
scope.draw(density, layoutDirection, Canvas(canvas), intrinsicSize) {
draw(intrinsicSize, alpha / 255f, colorFilter?.asComposeColorFilter())
}
}
override fun getIntrinsicWidth(): Int = intrinsicSize.width.toInt()
override fun getIntrinsicHeight(): Int = intrinsicSize.height.toInt()
override fun setAlpha(alpha: Int) { this.alpha = alpha }
override fun getAlpha(): Int = alpha
override fun setColorFilter(colorFilter: ColorFilter?) { this.colorFilter = colorFilter }
override fun getColorFilter(): ColorFilter? = colorFilter
override fun getOpacity() = PixelFormat.UNKNOWN
}
At first sight it seems to do what I want. Is this ok, or is there something wrong - both logic and code style-wise? Would it maybe make sense to remember this?cb
01/19/2022, 11:39 AMclass PainterDrawable(painter, density, layoutDirection): Drawable
+ optional remember
function.
• Cache the Canvas(canvas)
and CanvasDrawScope()
. There's no need to create one on every call if the canvas is the same.
• Coerce the alpha / 255f
within 0f,1f
. It could technically go out of that range with float ops.
• You'll want to use PixelFormat.TRANSPARENT
Feri Nagy
01/19/2022, 2:13 PMclass PainterDrawable(
private val painter: Painter,
private val density: Density,
private val layoutDirection: LayoutDirection
) : Drawable() {
private val scope = CanvasDrawScope()
private val canvasHolder = CanvasHolder()
private var alpha = 0xFF
private var colorFilter: ColorFilter? = null
override fun draw(canvas: android.graphics.Canvas) = canvasHolder.drawInto(canvas) {
scope.draw(density, layoutDirection, this, painter.intrinsicSize) {
with(painter) {
draw(
painter.intrinsicSize,
(alpha / 255f).coerceIn(0f, 1f),
colorFilter?.asComposeColorFilter()
)
}
}
}
override fun getIntrinsicWidth(): Int = painter.intrinsicSize.width.toInt()
override fun getIntrinsicHeight(): Int = painter.intrinsicSize.height.toInt()
override fun setAlpha(alpha: Int) { this.alpha = alpha }
override fun getAlpha(): Int = alpha
override fun setColorFilter(colorFilter: ColorFilter?) { this.colorFilter = colorFilter }
override fun getColorFilter(): ColorFilter? = colorFilter
override fun getOpacity() = PixelFormat.TRANSPARENT
}
As for the remember fun, I just was not sure, so I remembered everything 🤣 :
@Composable
fun rememberPainterDrawable(
painter: Painter,
density: Density = LocalDensity.current,
layoutDirection: LayoutDirection = LocalLayoutDirection.current
): Drawable = remember(painter, density, layoutDirection) { PainterDrawable(painter, density, layoutDirection) }
cb
01/19/2022, 10:54 PM