In my Jetpack Compose Android app, I used to have a "letter icon" Drawable
that basically just draws some text. Now I'm trying to migrate that Drawable to a Compose Painter
, but I can't find a way to draw text in the Painter. There are the DrawScope.drawText()
methods, but all of them require a TextMeasurer
. Usually, one would call rememberTextMeasurer()
to get one, but this doesn't seems to be possible in this case because onDraw()
is not a composable function. So I tried to instantiate a TextMeasurer
myself:
TextMeasurer(
defaultFontFamilyResolver = TODO(),
defaultDensity = drawContext.density,
defaultLayoutDirection = layoutDirection,
cacheSize = 8
)
Most of the constructor parameters are available in the DrawScope
, but I failed to get an instance of FontFamliy.Resolver
. FontFamliy.Resolver
is an interface only implemented by the internal class FontFamilyResolverImpl
and the only way to get an instance of it seems to be from the LocalFontFamilyResolver
composition local, which is also not accessible from the painter.
As a workaround, I managed to draw the text using DrawScope.drawIntoCanvas()
and Canvas::nativeInstance
and then using Android SDK APIs, like android.graphics.canvas.drawText()
, but I would prefer a Compose-only approach.
Am I missing something here or is it not possible to draw text in a Painter
using the current Compose APIs?
Thanks.
In my Jetpack Compose Android app, I used to have a "letter icon" Drawable
that basically just draws some text. Now I'm trying to migrate that Drawable to a Compose Painter
, but I can't find a way to draw text in the Painter. There are the DrawScope.drawText()
methods, but all of them require a TextMeasurer
. Usually, one would call rememberTextMeasurer()
to get one, but this doesn't seems to be possible in this case because onDraw()
is not a composable function. So I tried to instantiate a TextMeasurer
myself:
TextMeasurer(
defaultFontFamilyResolver = TODO(),
defaultDensity = drawContext.density,
defaultLayoutDirection = layoutDirection,
cacheSize = 8
)
Most of the constructor parameters are available in the DrawScope
, but I failed to get an instance of FontFamliy.Resolver
. FontFamliy.Resolver
is an interface only implemented by the internal class FontFamilyResolverImpl
and the only way to get an instance of it seems to be from the LocalFontFamilyResolver
composition local, which is also not accessible from the painter.
As a workaround, I managed to draw the text using DrawScope.drawIntoCanvas()
and Canvas::nativeInstance
and then using Android SDK APIs, like android.graphics.canvas.drawText()
, but I would prefer a Compose-only approach.
Am I missing something here or is it not possible to draw text in a Painter
using the current Compose APIs?
Thanks.
Share Improve this question asked Feb 15 at 18:33 TUXTUX 1371 silver badge5 bronze badges 01 Answer
Reset to default 1Usually, one would call
rememberTextMeasurer()
to get one, but this doesn't seems to be possible in this case becauseonDraw()
is not a composable function
You can always pass one in:
import androidxpose.foundation.Image
import androidxpose.runtime.Composable
import androidxpose.ui.geometry.Size
import androidxpose.ui.graphics.drawscope.DrawScope
import androidxpose.ui.graphics.painter.Painter
import androidxpose.ui.text.TextMeasurer
import androidxpose.ui.text.rememberTextMeasurer
public class TextPainter(public val textMeasurer: TextMeasurer) : Painter() {
override val intrinsicSize: Size = Size.Unspecified
override fun DrawScope.onDraw() {
TODO("something with the TextMeasurer")
}
}
@Composable
internal fun PainterTextTest() {
val textMeasurer = rememberTextMeasurer()
Image(
TextPainter(textMeasurer),
"this is some content"
)
}
Now I'm trying to migrate that Drawable to a Compose Painter
I am skeptical that this is the best solution for whatever your overall problem is, but it should be doable.