Jetpack compose 在文本中显示 html

Jetpack compose display html in text

我有一个包含 html 的字符串,如何在 Jetpack 撰写文本中显示它?

在 TextView 中,我会使用 Spanned 并执行如下操作:

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

如何使用 Jetpack compose 中的文本执行此操作?

遗憾的是,Jetpack compose 尚不支持 HTML...

那么,您可以做的是:

选项 1:创建您自己的 HTML 解析器

Jetpack compose 支持基本样式,例如粗体、颜色、字体等。因此您可以做的是遍历原始 HTML 文本并手动应用文本样式。

选项 2:将旧的 TextView 集成到您的 Jetpack compose 中。

请阅读:Adopting Compose in your app

谢谢。

您可以将旧的 TextView 集成到您的 Jetpack compose 中,如下所示:

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

更多信息:https://foso.github.io/Jetpack-Compose-Playground/viewinterop/androidview/

与 Yhondri 的答案相同,但如果您的目标是 api >24:

,则使用 HtmlCompat
@Composable
fun Html(text: String) {
    AndroidView(factory = { context ->
        TextView(context).apply {
            setText(HtmlCompat.fromHtml(text, HtmlCompat.FROM_HTML_MODE_LEGACY))
        }
    })
}

我已经这样做了,而不是在 AndroidView 中使用 TextView,它对我来说似乎工作得很好。下面的可组合项还会包裹文本并在您单击它时展开。

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