【问题标题】:HTML.fromHtml line breaks disappearingHTML.fromHtml 换行符消失
【发布时间】:2012-07-22 10:39:51
【问题描述】:

我从 EditText 框中获取跨区文本,并使用 HTML.toHtml 将其转换为 HTML 标记字符串。这工作正常。我已经验证该字符串是正确的,并且在适当的位置包含一个<br>。但是,当我必须将标记字符串转换回跨区文本以使用 HTML.fromHtml 填充 TextView 或 EditText 时,第一段末尾的<br>(或多个,如果它们存在)消失了。这意味着如果用户输入带有多个换行符的文本并希望保留该格式,它就会丢失。

我附上了一张图片来帮助说明这一点。第一个 EditText 是用户输入,它下面的 TextView 是它上面的 EditText 的 HTML.tohtml 结果,它下面的 EditText 使用 HTML.fromHtml 使用它上面的 TextView 中的字符串填充。如您所见,换行符已消失,多余的行也已消失。此外,当第二个编辑文本的跨区文本通过 HTML.toHtml 运行时,它现在会生成一个不同的 HTML 标记字符串。

我希望能够从第一个 EditText 中获取带有 HTML 标记的字符串并填充其他 TextViews 或 EditTexts 而不会丢失换行符和格式。

【问题讨论】:

    标签: android html formatting textview android-edittext


    【解决方案1】:

    我在尝试将 editText 内容保存/恢复到数据库时遇到了类似的问题。问题出在 Html.toHtml 中,它以某种方式跳过了线刹车:

        String src = "<p dir=\"ltr\">First line</p><p dir=\"ltr\">Second<br/><br/><br/></p><p dir=\"ltr\">Third</p>";
        EditText editText = new EditText(getContext());
        // All line brakes are correct after this
        editText.setText(new SpannedString(Html.fromHtml(src))); 
        String result = Html.toHtml(editText.getText()); // Here breaks are lost
        // Output :<p dir="ltr">First line</p><p dir="ltr">Second<br></p><p dir="ltr">Third</p>
    

    我已经通过使用自定义 toHtml 函数来序列化跨区文本来解决这个问题,并将所有 '\n' 替换为 ":

        public class HtmlParser {
            public static String toHtml(Spannable text) {
                final SpannableStringBuilder ssBuilder = new SpannableStringBuilder(text);
                int start, end;
    
                // Replace Style spans with <b></b> or <i></i>
                StyleSpan[] styleSpans = ssBuilder.getSpans(0, text.length(), StyleSpan.class);
                for (int i = styleSpans.length - 1; i >= 0; i--) {
                    StyleSpan span = styleSpans[i];
                    start = ssBuilder.getSpanStart(span);
                    end = ssBuilder.getSpanEnd(span);
                    ssBuilder.removeSpan(span);
                    if (span.getStyle() == Typeface.BOLD) {
                        ssBuilder.insert(start, "<b>");
                        ssBuilder.insert(end + 3, "</b>");
                    } else if (span.getStyle() == Typeface.ITALIC) {
                        ssBuilder.insert(start, "<i>");
                        ssBuilder.insert(end + 3, "</i>");
                    }
                }
    
                // Replace underline spans with <u></u>
                UnderlineSpan[] underSpans = ssBuilder.getSpans(0, ssBuilder.length(), UnderlineSpan.class);
                for (int i = underSpans.length - 1; i >= 0; i--) {
                    UnderlineSpan span = underSpans[i];
                    start = ssBuilder.getSpanStart(span);
                    end = ssBuilder.getSpanEnd(span);
                    ssBuilder.removeSpan(span);
                    ssBuilder.insert(start, "<u>");
                    ssBuilder.insert(end + 3, "</u>");
                }
                replace(ssBuilder, '\n', "<br/>");
    
                return ssBuilder.toString();
            }
    
            private static void replace(SpannableStringBuilder b, char oldChar, String newStr) {
                for (int i = b.length() - 1; i >= 0; i--) {
                    if (b.charAt(i) == oldChar) {
                        b.replace(i, i + 1, newStr);
                    }
                }
            }
    }
    

    事实证明,这种方式比默认的 Html.toHtml() 快了大约 4 倍:我用大约 20 个页面和 200 个跨度做了一个基准测试:

        Editable ed = editText.getText(); // Here is a Tao Te Ching :)
        String result = "";
        DebugHelper.startMeasure("Custom");
        for (int i = 0; i < 10; i++) {
            result = HtmlParserHelper.toHtml(ed);
        }
        DebugHelper.stopMeasure("Custom"); // 19 ms
    
        DebugHelper.startMeasure("Def");
        for (int i = 0; i < 10; i++) {
            result = Html.toHtml(ed);
        }
        DebugHelper.stopMeasure("Def"); // 85 ms
    

    【讨论】:

    • 这确实是一个可爱的答案只回答谈论有问题的 Html.toHtml 功能。你节省了我很多很多的努力。不能说足够的感谢! :) 干杯!
    • 很高兴提到这也解决了我的another problem :)
    【解决方案2】:

    替换 /n =>

    例子

    j

    到:



    j

    【讨论】:

      【解决方案3】:

      我也遇到了这个问题,我找不到简单的“转换”或类似的解决方案。请注意一些重要的事情,当用户按下“回车”时,java 会生成特殊字符 \n,但在 HTML 中没有这样的换行格式。是&lt;br /&gt;

      所以我所做的是将纯文本中的某些特定CharSequences 替换为替代HTML 格式。就我而言,只有“输入”字符,所以没有那么混乱。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-03-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多