繁体   English   中英

Android HtmlCompat.toHtml(Spanned) 返回不正确嵌套的 HTML 标签

[英]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 嵌套不正确。

  • Hello World :输出<p dir="ltr><b><i>Hello world</b></i></p>

如您所见,应用的标签是<b><i> </b></i>而不是<b><i> </i></b>


如果文本没有格式化,或者是粗体或斜体,则返回正确的 HTML:

  • Hello World:输出<p dir="ltr>Hello world</p>
  • Hello World :输出<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.

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