简体   繁体   中英

Jetpack compose display html in text

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?

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))
        }
    })
}

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/

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.

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
            }
        }
    )
}

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM