HTML.fromHtml line breaks disappearing

后端 未结 3 1150
无人共我
无人共我 2021-01-02 03:55

I am taking Spanned Text from an EditText box and converting it to a HTML tagged string using HTML.toHtml. This works fine. I have verified that the string is correct and co

相关标签:
3条回答
  • 2021-01-02 04:27

    I had similar problem when I was trying to save/restore editText content to db. The problem is in Html.toHtml, it somehow skips line brakes:

        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>
    

    I've solved this by using custom toHtml function to serialize spanned text, and replaced all '\n' with "< 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);
                    }
                }
            }
    }
    

    Also it turned out that this way is faster in about 4 times that default Html.toHtml(): I've made a benchmark with about 20 pages and 200 spans:

        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
    
    0 讨论(0)
  • 2021-01-02 04:31

    Replace /n => < br>< br>

    example

    < p>hi< /p> < p>j< /p>

    to:

    < p>hi< /p>< br>< br>< p>j< /p>

    0 讨论(0)
  • 2021-01-02 04:37

    I also had this problem and I could not find an easy "transform" or something alike solution. Note something important, when the user presses "enter" java produces the special character \n but in HTML there is no such format for line breaking. It is the <br />.

    So what I have done was to replace some specific CharSequences, from the plain text, by the alternative HTML format. In my case there was only the "enter" character so it was not that messy.

    0 讨论(0)
提交回复
热议问题