Jetpack Compose 如何在文本中显示 HTML

12

我有一个包含 HTML 的字符串,如何在 Jetpack Compose Text 中显示它?

在 TextView 中,我可以使用 Spanned 并执行以下操作:

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

我该如何使用Jetpack Compose中的文本实现这个功能?


2
您需要创建一个AnnotatedString。目前我不知道任何现有的HTML->AnnotatedString转换库,但我相信总会有人会创造出来。 - CommonsWare
也许这个库可以满足您的需求。 - Emmanuel Guerra
5个回答

6

如果你的目标API是>24,则可以像Yhondri一样使用HtmlCompat:

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

3

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

我将你的ExpandingText复制到了一个新的kt文件中,但它对我不起作用。此主题中的示例HTML https://stackoverflow.com/questions/72736497/html-in-jetpack-compose-text “团队”不是链接,点击不会打开浏览器。 - Ralf Wickum

2

很遗憾,Jetpack compose目前尚不支持HTML...

因此,您可以采取以下措施:

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

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

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

请阅读: Adopting Compose in your app

谢谢。


1
我会接受这个答案,因为现在似乎只有这些选项。 - Stephan
@Stephan 是的,目前这就是我们拥有的全部...谢谢。 - minchaej

1

0

您可以使用以下代码:

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

使用 withStyle 应用 HTML 标签,并在其中使用 append() 添加字符串。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接