androidkotlinandroid-jetpack-composeandroid-jetpack-compose-text

Android Jetpack Compose: How to show styled Text from string resources


I have a string in my strings.xml which is localized for different languages. The strings are styled with Html tags for each localization.

Using Android TextView, I was able to show the styled text just fine by reading the string resources.

Considering that Jetpack Compose currently (1.0.0-rc02) does not support Html tags, I tried using TextView inside an AndroidView composable following Official Docs: https://developer.android.com/jetpack/compose/interop/interop-apis#views-in-compose

Example of what I tried:

@Composable
fun StyledText(text: String, modifier: Modifier = Modifier) {
    AndroidView(
            modifier = modifier,
            factory = { context -> TextView(context) },
            update = {
                it.text = HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_COMPACT)
            }
    )
}

The text in strings.xml file:

<string name="styled_text">Sample text with <b>bold styling</b> to test</string>

However, using stringResource(id = R.string.styled_text) provides the text without the Html tags.

Is there a way to show text from string resources with Html styles in Jetpack Compose?


The following two questions are similar, but they do not read the string from resources:

Jetpack compose display html in text

Android Compose: How to use HTML tags in a Text view


Solution

  • stringResource under the hood uses resources.getString, which discards any styled information. You need to create something like textResource to get the raw value:

    @Composable
    @ReadOnlyComposable
    fun textResource(@StringRes id: Int): CharSequence =
        LocalContext.current.resources.getText(id)
    

    And use it like this:

    StyledText(textResource(id = R.string.foo))
    
    @Composable
    fun StyledText(text: CharSequence, modifier: Modifier = Modifier) {
        AndroidView(
            modifier = modifier,
            factory = { context -> TextView(context) },
            update = {
                it.text = text
            }
        )
    }