HTML.fromHtml исчезают разрывы строк

Я беру Spanned Text из поля EditText и преобразую его в строку с тегом HTML, используя HTML.toHtml. Это отлично работает. Я проверил, что строка правильная и содержит <br> в соответствующем месте. Однако, когда мне нужно преобразовать помеченную строку обратно в составной текст, чтобы заполнить TextView или EditText, используя HTML.fromHtml, <br> (или несколько, если они присутствуют) в конце первого абзаца исчезают. Это означает, что если пользователь вводит текст с несколькими переносами строк и хочет сохранить это форматирование, он теряется.

Я приложил картинку, чтобы проиллюстрировать это. Первый EditText - это пользовательский ввод, TextView. Ниже это HTML.tohtml результат EditText над ним, EditText под ним заполняется с использованием HTML.fromHtml, используя строку в TextView над ним. Как вы можете видеть, разрывы строк исчезли, как и дополнительные строки. Кроме того, когда составной текст второго редактируемого текста проходит через HTML.toHtml, он теперь создает другую строку с тегом HTML.

enter image description here

Я хотел бы иметь возможность взять строку с тегом HTML из первого EditText и заполнить другие TextViews или EditTexts без потери разрывов строк и форматирования.

Ответ 1

У меня также была эта проблема, и я не мог найти легкое "преобразование" или что-то подобное. Обратите внимание на что-то важное, когда пользователь нажимает "enter" java создает специальный символ \n, но в HTML нет такого формата для прерывания строки. Это <br />.

Так что я сделал, чтобы заменить некоторые конкретные CharSequence s, из обычного текста, альтернативным HTML-форматом. В моем случае был только символ "enter", поэтому он не был таким беспорядочным.

Ответ 2

У меня была аналогичная проблема, когда я пытался сохранить/восстановить содержимое 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);
                }
            }
        }
}

Также выяснилось, что этот способ быстрее примерно в 4 раза превышает значение по умолчанию Html.toHtml(): я сделал тест с примерно 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

Ответ 3

Заменить/n = > < ш > < ш >

Пример

<p> привет </p> <p> J </p>

в

<p> привет </p> < ш > < ш > <p> J </p>

Ответ 4

используйте заполнитель relpce "\ r\n" перед вызовом Html.fromHtml, затем Replace back, используйте флаг Html.FROM_HTML_MODE_COMPACT для вызова Html.fromHtml

 String placeHolder = "123abc";
 String temp = htmlNote.replace("\r\n", placeHolder);
 Spanned spanned = Html.fromHtml(temp, Html.FROM_HTML_MODE_COMPACT);
 String replace = spanned.toString().replace(placeHolder, "\r\n");
 return replace;