Jetpack compose display html in text
Asked Answered
R

5

15

I have a string that contains html, how can I display this in a Jetpack compose Text?

In a TextView I would use a Spanned and do something like:

TextView.setText(Html.fromHtml("<p>something", HtmlCompat.FROM_HTML_MODE_LEGACY)

How can I do this with Text from Jetpack compose?

Roulette answered 22/6, 2021 at 14:56 Comment(2)
You would need to create an AnnotatedString. I am not aware of any existing HTML->AnnotatedString converter libraries at this time, though I am sure that somebody will eventually create one.Gyp
Maybe this library can suit your needs.Kitti
A
3

Unfortunately, Jetpack compose does NOT support HTML yet...

So, what you could do is:

Option 1: Create your own HTML parser

Jetpack compose supports basic styling such as Bold, color, font etc.. So what you can do is loop through the original HTML text and apply text style manually.

Option 2: Integrate the old TextView into your Jetpack compose.

Please read: Adopting Compose in your app

Thanks.

Algonkian answered 22/6, 2021 at 16:55 Comment(2)
I'm going to accept this answer, since it seems like those are the only options for now.Roulette
@Roulette Yup, It is all we have as of now... Thanks.Algonkian
D
8

Same answer as Yhondri, but using HtmlCompat if you are targeting api >24:

@Composable
fun Html(text: String) {
    AndroidView(factory = { context ->
        TextView(context).apply {
            setText(HtmlCompat.fromHtml(text, HtmlCompat.FROM_HTML_MODE_LEGACY))
        }
    })
}
Dine answered 16/8, 2021 at 9:23 Comment(0)
A
3

Unfortunately, Jetpack compose does NOT support HTML yet...

So, what you could do is:

Option 1: Create your own HTML parser

Jetpack compose supports basic styling such as Bold, color, font etc.. So what you can do is loop through the original HTML text and apply text style manually.

Option 2: Integrate the old TextView into your Jetpack compose.

Please read: Adopting Compose in your app

Thanks.

Algonkian answered 22/6, 2021 at 16:55 Comment(2)
I'm going to accept this answer, since it seems like those are the only options for now.Roulette
@Roulette Yup, It is all we have as of now... Thanks.Algonkian
O
3

You can integrate the old TextView into your Jetpack compose like follows:

AndroidView(factory = { context ->
                    TextView(context).apply {
                        text = Html.fromHtml(your_html)
                    }
                })

More info: https://foso.github.io/Jetpack-Compose-Playground/viewinterop/androidview/

Oruro answered 5/7, 2021 at 20:16 Comment(0)
K
3

I have done it this way instead of using TextView in AndroidView and it seems to work quite well for me. The below composable also wraps up the text and expands when you click on it.

@Composable
fun ExpandingText(
    description: String,
    modifier: Modifier = Modifier,
    textStyle: TextStyle = MaterialTheme.typography.body2,
    expandable: Boolean = true,
    collapsedMaxLines: Int = 3,
    expandedMaxLines: Int = Int.MAX_VALUE,
) {
    val text = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        Html.fromHtml(description, Html.FROM_HTML_MODE_LEGACY)
    } else {
        HtmlCompat.fromHtml(description, HtmlCompat.FROM_HTML_MODE_LEGACY)
    }

    var canTextExpand by remember(text) { mutableStateOf(true) }
    var expanded by remember { mutableStateOf(false) }
    val interactionSource = remember { MutableInteractionSource() }

    Text(
        text = text.toString(),
        style = textStyle,
        overflow = TextOverflow.Ellipsis,
        maxLines = if (expanded) expandedMaxLines else collapsedMaxLines,
        modifier = Modifier
            .clickable(
                enabled = expandable && canTextExpand,
                onClick = { expanded = !expanded },
                indication = rememberRipple(bounded = true),
                interactionSource = interactionSource,
            )
            .animateContentSize(animationSpec = spring())
            .then(modifier),
        onTextLayout = {
            if (!expanded) {
                canTextExpand = it.hasVisualOverflow
            }
        }
    )
}
Kopans answered 11/5, 2022 at 9:52 Comment(2)
I copied your ExpandingText into a new kt file but it does not work for me. Sample HTML in this topic #72736997 The "team" is not link and click does not open browser.Discommon
With this you loose the visual text attributes like bold, italic, colors, etc.Naraka
H
0

you can use the code below:

@Composable
private fun TextHtml() {
   Text(text = buildAnnotatedString {
                    withStyle(style = SpanStyle(color = Gray600)) {
                        append("normal text")
                    }
                    withStyle(style = SpanStyle(fontWeight = FontWeight.Bold,color = Gray700)) {
                        append("bold text ")
                    }
                })
}

use withStyle to apply the html tags and use append() inside it to add the string

Homochromous answered 14/12, 2022 at 14:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.