What's the correct way of rendering html string in compose? Something very similar to `HtmlCompat.fr...
r
What's the correct way of rendering html string in compose? Something very similar to
HtmlCompat.fromHtml()
in textView.
👀 1
s
Copy code
fun charSequenceResource(@StringRes id: Int): CharSequence =
    LocalContext.current.resources.getText(id)

fun CharSequence.toAnnotatedString(): AnnotatedString = buildAnnotatedString {
    if (this@toAnnotatedString !is Spanned) {
        append(this.toString())
        return@buildAnnotatedString
    }

    val spanned = this@toAnnotatedString
    append(spanned.toString())
    getSpans(0, spanned.length, Any::class.java).forEach { span ->
        val start = getSpanStart(span)
        val end = getSpanEnd(span)
        when (span) {
            is StyleSpan -> when (span.style) {
                Typeface.BOLD -> addStyle(SpanStyle(fontWeight = FontWeight.Bold), start, end)
                Typeface.ITALIC -> addStyle(SpanStyle(fontStyle = FontStyle.Italic), start, end)
                Typeface.BOLD_ITALIC -> addStyle(
                    SpanStyle(
                        fontWeight = FontWeight.Bold,
                        fontStyle = FontStyle.Italic
                    ), start, end
                )
            }
            is UnderlineSpan -> addStyle(
                SpanStyle(textDecoration = TextDecoration.Underline),
                start,
                end
            )
            is ForegroundColorSpan -> addStyle(
                SpanStyle(color = Color(span.foregroundColor)),
                start,
                end
            )
        }
    }
}

title = charSequenceResource(R.string.resource).toAnnotatedString(),
or use
Copy code
buildAnnotatedString
r
Can you explain please, how it's converting HTML into an AnnotatedString.
I couldn't find any better solution but to use
TextView
Copy code
AndroidView(
            modifier = modifier,
            factory = { context -> TextView(context) },
            update = { it.text = HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_COMPACT) }
    )
Source - https://stackoverflow.com/questions/66494838/android-compose-how-to-use-html-tags-in-a-text-view
s
i gave you a better solution earlier..
z
Compose doesn’t have built-in support for converting HTML into `AnnotatedString`s. Artem’s solution asks the framework to parse HTML into a string with android spans, and then converts the spans to compose style annotations.
🙏 1
r
yeah, i failed to see in above code - how any HTML string (coming from server) can be parsed using above code. As you mentioned compose doesn't have built-in support for HTML into
AnnotatedString
and i am not sure what sub-set of HTML tags or symbols server can give. I believe the best solution in this case is to rely on
TextView
z
TextView itself only supports a very small subset of HTML, so if you don't know what data you're getting from the server you are eventually gonna have a bad time with that approach too. If you are ok with that risk though, use the Html class to parse an arbitrary string.
r
yeah, i meant converting html string to spanned text using
HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_COMPACT)
and then setting it up in textview in my composable.
Copy code
AndroidView(
            modifier = modifier,
            factory = { context -> TextView(context) },
            update = { it.text = HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_COMPACT) }
    )
This, way i won't have to check for different styles inside when block - Artem's solution. And i also noticed, it being the recommended solution. https://developer.android.com/codelabs/jetpack-compose-migration?continue=https%3A%2F%2[…]veloper.android.com%2Fcodelabs%2Fjetpack-compose-migration
3655 Views