8

在我的应用程序中,我使用 Html.fromHtml(string).toString 方法来删​​除<p>在解析一些 JSON 时收到的一些标签。

如果我留下<p>标签,文本完全适合背景(背景是一个相对布局,高度和宽度都有 wrap_content。)但是,如果我使用 fromHtml 删除<p>标签,突然在文本下方有一个巨大的空间,我相信 fromHtml 方法最后会添加空格吗?

有任何想法吗?

编辑:

以下是截图:http: //imgur.com/a/zIZNo

<p>标签的就是不使用fromHtml的,很明显!:)

编辑2:已找到解决方案,请参阅下面的答案。感谢 Andro Selva 帮助我告诉我/n正在添加的隐藏!

4

5 回答 5

13

找到了解决办法:

fromHtml 返回 Spanned 类型。因此,我将返回的内容分配给变量,将其转换为字符串,然后对其使用 .trim() 方法。

它在最后删除了所有空白。

于 2012-08-09T11:59:20.107 回答
5

是的,您的想法确实是正确的。它增加了底部的空间。但在此之前,让我解释一下这是如何工作的。

您必须查看 HTML 类以了解它是如何工作的。

简单来说,它是这样工作的:每当你的Html类查看<p>标签时,它所做的只是在末尾附加两个“\n”字符。

在这种情况下,您在底部看到的空白实际上是因为在段落末尾附加了两个 \n 。

我添加了负责此操作的 Html 类的实际方法,

    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");

    }
}

如果要覆盖此操作,则必须覆盖 Html 类本身,这有点棘手,无法在此处完成。

编辑

这是 Html 类的链接,

html类

于 2012-08-09T11:44:31.400 回答
3

如果您尝试在对象中使用它或尝试将其安装在特定位置,请尝试使用<a>标签而不是 a <p><p>在末尾添加回车符,a 不写,但您必须记住\n自己用<b>, 和你可以保持风格

于 2015-11-13T17:59:10.287 回答
0

@Andro Selva 的解释是正确的,对此没有什么可做的。令人沮丧的是,API 24 及更高版本在调用中包含标志后情况变得更好

Spanned fromHtml (String source, 
                int flags, 
                Html.ImageGetter imageGetter, 
                Html.TagHandler tagHandler);

我怀疑FROM_HTML_SEPARATOR_LINE_BREAK_PARAGRAPH标志会将标准段落终止的双“\n\n”减少到换行符的单个“\n”

鉴于 Android 版本的历史 ~ 我负担不起专门为 Android API 24+ 编写软件!所以...我找到了一个包含 2 个额外自定义标签的 kludge 解决方案。

1. <scale factor="x.xx">... </scale>
2. <default>... </default>

都通过这个方法调用RelativeSizeSpan类

private void ProcessRelativeSizeTag(float scalefactor, boolean opening, Editable output) {
                int len = output.length();
                if (opening) {
                    System.out.println("scalefactor open: " + scalefactor);
                    output.setSpan(new RelativeSizeSpan(scalefactor), len, len,
                            Spannable.SPAN_MARK_MARK);
                } else {
                    Object obj = getLast(output, RelativeSizeSpan.class);
                    int where = output.getSpanStart(obj);
                    scalefactor = ((RelativeSizeSpan)obj).getSizeChange();
                    output.removeSpan(obj);
                    System.out.println("scalefactor close: " + scalefactor);
                    if (where != len) {
                        output.setSpan(new RelativeSizeSpan(scalefactor), where, len,
                                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                    }
                }
            }

从提供给Html.fromHtml方法的自定义 TagHandler 调用,即:

private static class CustomTagHandler implements Html.TagHandler {

    private void ProcessRelativeSizeTag(float scalefactor, boolean opening, Editable output) {
            int len = output.length();
            if (opening) {
                //mSizeStack.push(scalefactor);
                System.out.println("scalefactor open: " + scalefactor);
                output.setSpan(new RelativeSizeSpan(scalefactor), len, len,
                        Spannable.SPAN_MARK_MARK);
            } else {
                Object obj = getLast(output, RelativeSizeSpan.class);
                int where = output.getSpanStart(obj);
                scalefactor = ((RelativeSizeSpan)obj).getSizeChange();

                output.removeSpan(obj);

                //scalefactor = (float)mSizeStack.pop();
                System.out.println("scalefactor close: " + scalefactor);
                if (where != len) {
                    output.setSpan(new RelativeSizeSpan(scalefactor), where, len,
                            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                }
            }
        }
...
        final HashMap<String, String> mAttributes = new HashMap<>();

        @Override
        public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {
            String Attr;
            processAttributes(xmlReader);
            if ("default".equalsIgnoreCase(tag)) {
                ProcessRelativeSizeTag(mDefaultTextSize, opening, output);
                return;
            }

            if ("scale".equalsIgnoreCase(tag)) {
                Attr = mAttributes.get("factor");
                if (Attr != null && !Attr.isEmpty()) {
                    float factor = parseFloat(Attr);
                    if (factor > 0)
                        ProcessRelativeSizeTag(factor, opening, output);
                }
                return;
... 
            }

       }

要使用,我将Textview对象的文本大小设置为1。即1像素!然后我在变量中设置所需的真实文本大小mDefaultTextSize。我在一个htmlTextView扩展TextView为:

public class htmlTextView extends AppCompatTextView {
    static Typeface mLogo;
    static Typeface mGAMZ;
    static Typeface mBrush;
    static Typeface mStandard;
    int GS_PAINTFLAGS = FILTER_BITMAP_FLAG | ANTI_ALIAS_FLAG | SUBPIXEL_TEXT_FLAG | HINTING_ON;
    static float mDefaultTextSize;
    static Typeface mDefaultTypeface;
etc

}

其中包括公共方法

public void setDefaultTextMetrics(String face, float defaultTextSize) {
        mDefaultTypeface = mStandard;
        if (face != null) {
            if ("gamz".equalsIgnoreCase(face)) {
                mDefaultTypeface = mGAMZ;
            } else {
                if ("brush".equalsIgnoreCase(face)) {
                    mDefaultTypeface = mBrush;
                }
            }
        }
        setTypeface(mDefaultTypeface);
        setTextSize(1);
        mDefaultTextSize = defaultTextSize;
    }

一个简单的((htmlTextView)tv).setDefaultTextMetrics(null, 30);调用设置我htmlTextView使用我的标准字体作为默认字体,文本大小为 30。

然后当我给它这个例子以在 fromHtml 中使用时:

<string name="htmlqwert">
<![CDATA[
        <p><default><scale factor="1.5"><box> qwertQWERT </box></scale></default></p>
        <p><default><scale factor="1.5"><box> qwertQWERT </box></scale></default></p>
        <p><default><scale factor="1.5"><box> qwertQWERT </box></scale></default></p>
        <p><default><scale factor="1.5"><box> qwertQWERT </box></scale></default></p>
]]>
</string>

我的自定义标签<box>只是让我突出显示文本的背景。请参见附图,其中显示了一个使用<default>标签的结果,其中TextView文本大小设置为 1,<default>标签调用 aRelevantSizeSpan的因子为 30,其中一个具有:

<string name="htmlqwert">
    <![CDATA[
            <p><scale factor="1.5"><box> qwertQWERT </box></scale></p>
            <p><scale factor="1.5"><box>qwertQWERT</box></scale></p>
            <p><scale factor="1.5"><box>qwertQWERT</box></scale></p>
            <p><scale factor="1.5"><box>qwertQWERT</box></scale></p>
    ]]>
    </string>

不使用<default>标签,而是将TextView文本大小设置为 30。在第一种情况下,额外的新行仍然存在,但它只有 1 个像素高!

<scale factor="1.5">...</scale>注意标签没有真正的意义。它们只是从其他测试中遗留下来的人工制品。

结果:下面的两个示例在段落之间都有 2 个换行符,但在左侧的那个中,其中一个行只有 1 个像素高。我将留给读者弄清楚如何将其减少到零,但不要使用 0 的文本大小

于 2017-08-04T17:25:58.397 回答
0

这个解决方案对我有用 创建一个辅助方法来替换所有段落的开始和结束标记,并用空字符替换所有。

@Nullable
public static String removeParagraphTags(@Nullable String input) {
    if (input == null) {
        return null;
    }
    return input.replaceAll("<p>", "").replaceAll("</p>", "");
}

和用法

  String input = "<p>This is some text in a paragraph.</p>";
HtmlCompat.fromHtml(StringUtils.removeParagraphTags(input),HtmlCompat.FROM_HTML_MODE_COMPACT)
于 2021-04-30T06:54:10.247 回答