11

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

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

在此处输入图像描述

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

4

3 回答 3

11

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

所以我所做的就是用CharSequence另一种 HTML 格式替换纯文本中的一些特定 s。就我而言,只有“输入”字符,所以它不是那么混乱。

于 2012-07-24T07:35:41.600 回答
7

当我尝试将 editText 内容保存/恢复到 db 时,我遇到了类似的问题。问题出在 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' 替换为 "< br/>:

    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
于 2016-03-07T06:46:12.330 回答
0

替换 /n => < br>< br>

例子

<p>嗨</p> <p>j</p>

至:

<p>嗨</p><br><br><p>j</p>

于 2014-05-02T07:53:15.523 回答