使用HTML内容在TextView上进行额外填充

Ben*_*fez 33 html android textview

我有这个TextView:

<TextView
    android:id="@+id/issue_journal_item_notes"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignLeft="@+id/issue_journal_item_details"
    android:layout_below="@+id/issue_journal_item_details"
    android:background="@drawable/journal_item_notes_background"
    android:padding="8dp"
    android:text="issue_journal_item_notes"
    android:textIsSelectable="true" />
Run Code Online (Sandbox Code Playgroud)

我填写这个:

String html = "<p>Hi,<br/>Do you think you could get a logcat during the crash? That seems really strange, especially the fact that it makes Android reboot.<br/>You can get the SDK here: http://developer.android.com/sdk/index.html<br/>(needed for logcat)</p>";
theTextView.setText(Html.fromHtml(html));
Run Code Online (Sandbox Code Playgroud)

这导致:

结果截图

"受让人......"是另一个TextView.
TextView是灰色背景的人.它的界限清晰可见,浅灰色.左边的左侧深灰色条是背景的一部分,所以它也是TextView

我们可以清楚地看到8dp方形填充.但是,底部的空白区域是什么?它是某种填充,但我没有在XML或代码中设置它!

如果有人问,我需要 HTML支持,因为不像在上面的截图中显示,该内容可能有一些HTML内容(<pre>,<i>,<b>等).

MH.*_*MH. 58

你看到的额外"填充"实际上只是一个换行符,然后是另一个换行符:

在此输入图像描述

当您深入了解Html.fromHtml(...)实现时,您会遇到以下处理段落标记的方法:

private static void handleP(SpannableStringBuilder text) {
    int len = text.length();

    if (len >= 1 && text.charAt(len - 1) == '\n') {
        if (len >= 2 && text.charAt(len - 2) == '\n') {
            return;
        }

        text.append("\n");
        return;
    }

    if (len != 0) {
        text.append("\n\n");
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的代码段取自Android 4.2.2源代码.逻辑非常简单,并且基本上确保每个段落标记结束\n\n,以在两个元素块之间给出视觉差距.这意味着框架不会考虑整个Html文本是仅包含一个段落(您的案例)还是多个连续的paragaps - 在转换段落的末尾总会有两个换行符.

话虽这么说,如果你知道你总是处理一个段落,最简单的解决方案是在将它包装之前删除它Html.fromHtml(...).这几乎是其他一个答案中提出的内容.

现在,既然你提到这不是一个真正的选择,那么另一种方法就是"修剪"结果Html.fromHtml(...),删除任何尾随的空格.Android返回一个Spanned(通常这是一个SpannableStringBuilder对象),遗憾的是,它没有内置trim()方法.尽管如此,或者借用其中一种可用的实现方式并不是太棘手.

方法的基本实现trim()有点像这样:

public static CharSequence trim(CharSequence s, int start, int end) {
    while (start < end && Character.isWhitespace(s.charAt(start))) {
        start++;
    }

    while (end > start && Character.isWhitespace(s.charAt(end - 1))) {
        end--;
    }

    return s.subSequence(start, end);
}
Run Code Online (Sandbox Code Playgroud)

要使用它,请将原始代码更改为:

String html = "<p>Hi,<br/>Do you think you could get a logcat during the crash? That seems really strange, especially the fact that it makes Android reboot.<br/>You can get the SDK here: http://developer.android.com/sdk/index.html<br/>(needed for logcat)</p>";
CharSequence trimmed = trim(Html.fromHtml(html));
theTextView.setText(trimmed);
Run Code Online (Sandbox Code Playgroud)

瞧,前后:

在此输入图像描述

  • 听起来你没有试一试就驳回了我的建议 - 考虑到我投入的时间和我给出的所有现成的代码,这有点忘恩负义.请注意`Spanned实现CharSequence`(就像Java中代表文本内容的所有类一样),因此对后者起作用的任何东西也都适用于前者.另外,修剪样式/标记的`CharSequence`(或者如果你喜欢的话,`Spanned`)与修剪原始输入`String`不同.我建议你先尝试一下,这应该不到1分钟...... (8认同)

Kir*_* A. 14

您也可以使用以下代码

 myTextView.setText(noTrailingwhiteLines(html));

private CharSequence noTrailingwhiteLines(CharSequence text) {

    while (text.charAt(text.length() - 1) == '\n') {
        text = text.subSequence(0, text.length() - 1);
    }
    return text;
}
Run Code Online (Sandbox Code Playgroud)


Pra*_*ena 8

Html.fromHtml(html)返回Spannable以便您可以通过调用toString()然后trim将字符串设置为字符串将其转换为字符串textview

String html = "<p>Hi,<br/>Do you think you could get a logcat during the crash? That seems really strange, especially the fact that it makes Android reboot.<br/>You can get the SDK here: http://developer.android.com/sdk/index.html<br/>(needed for logcat)</p>";
theTextView.setText(Html.fromHtml(html).toString().trim());
Run Code Online (Sandbox Code Playgroud)

  • 它首先杀死了您使用 Html 的所有格式。 (5认同)