簡體   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