[英]Html.toHtml with Spanned cast (ClassCastException) <Android>
[英]Android HtmlCompat.toHtml(Spanned) returns improperly nested HTML tags
我有一个 Edittext(使用视图绑定的 binding.text),其中包含使用 StyleSpan 设置样式的文本,即粗体和斜体。 为了保存格式化文本,我在 Kotlin 中使用 HtmlCompat.toHtml(spannable) 将其转换为 HTML。
var htmlString = HtmlCompat.toHtml(SpannableString(binding.text.text), HtmlCompat.FROM_HTML_MODE_LEGACY)
但是,如果文本同时应用了粗体和斜体,则返回的 HTML 嵌套不正确。
<p dir="ltr><b><i>Hello world</b></i></p>
如您所见,应用的标签是<b><i> </b></i>
而不是<b><i> </i></b>
。
如果文本没有格式化,或者是粗体或斜体,则返回正确的 HTML:
<p dir="ltr>Hello world</p>
<p dir="ltr><b>Hello world</b></p>
我想 function 喜欢把<b>
和</b>
放在第一位,而不是<i>
和</i>
,但这会导致奇怪的结果,如图所示。 所以问题是:如何让 function 返回正确格式的 HTML?
您的顺序是对的,尽管 HTML 仍应在浏览器中正确显示。 违规代码在Html.java中。 以下是<b></b>
和<i></i>
的翻译位置:
...
for (int j = 0; j < style.length; j++) {
...
if (style[j] instanceof StyleSpan) {
int s = ((StyleSpan) style[j]).getStyle();
if ((s & Typeface.BOLD) != 0) {
out.append("<b>");
}
if ((s & Typeface.ITALIC) != 0) {
out.append("<i>");
}
}
...
for (int j = style.length - 1; j >= 0; j--) {
,,,
if (style[j] instanceof StyleSpan) {
int s = ((StyleSpan) style[j]).getStyle();
if ((s & Typeface.BOLD) != 0) {
out.append("</b>");
}
if ((s & Typeface.ITALIC) != 0) {
out.append("</i>");
}
}
style
是一个跨度数组。 此代码通过跨度向前扫描以放置开始标签,并向后扫描以关闭标签。 因此,如果您的粗体跨度和斜体跨度是跨越相同文本的不同跨度,那么此代码将生成正确嵌套的标签。
但是,如果一个StyleSpan指定了斜体和粗体,则标记顺序将与您报告的<b><i></b></i>
相同。 输出结束标签的代码应该将<i>
放在b
之前。 这看起来像一个错误,应该报告。
我假设您有一个StyleSpan是粗斜体跨度。 解决方法是将该跨度拆分为两个单独的跨度 - 一个粗体跨度和一个斜体跨度。 然后代码应该按预期工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.