Android TextView 上支持的 html 标签 [英] Supported html tags on Android TextView

查看:53
本文介绍了Android TextView 上支持的 html 标签的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要 Android TextView 上支持的 HTML 标记的正式列表.我正在使用 textView.setText(Html.fromHtml(label)); 但我不知道支持哪些标签.

解决方案

注意:

这以 API 27 为目标.不保证早期版本支持此列表中显示的标签,以后的版本相同(它们可以被删除).有关适用列表,请参阅适用 API 版本的等效类.


似乎这些都没有记录在任何地方(更正,2021 年:不再是这种情况),并且没有具体的标签添加时间列表(2021 年:情况似乎仍然如此).我认为 HTML 标记需要在 somewhere 中声明,如果不在文档中,至少在代码中.幸运的是,Android 的 HTML 解析非常简单,可以轻松理解相关位,而无需过多地翻查垃圾箱.

对于未来的版本:您可以使用 IntelliJ 或其他一些 IDE 来探索 Html.java 的源代码,或者您可以随时访问 AOSP 站点或等效的 GitHub 存储库.使用 IDE 可能是最简单的选择.

Html#fromHtml(String, int) 调用 Html#fromHtml(String, Int, ImageGetter, TagHandler.最后一个方法创建一个 HtmlToSpannedConverter,并返回转换的结果.我挖掘了那个代码,我发现了 这个方法:

<块引用>

private void handleStartTag(String tag, Attributes attributes) {

 if (tag.equalsIgnoreCase("br")) {//我们不需要处理这个.TagSoup 将确保有一个 </br>对于每个 <br>//这样我们就可以在处理关闭标签时安全地发出换行符.} else if (tag.equalsIgnoreCase("p")) {startBlockElement(mSpannableStringBuilder, 属性, getMarginParagraph());startCssStyle(mSpannableStringBuilder, 属性);} else if (tag.equalsIgnoreCase("ul")) {startBlockElement(mSpannableStringBuilder, 属性, getMarginList());} else if (tag.equalsIgnoreCase("li")) {startLi(mSpannableStringBuilder, 属性);} else if (tag.equalsIgnoreCase(div")) {startBlockElement(mSpannableStringBuilder, 属性, getMarginDiv());} else if (tag.equalsIgnoreCase("span")) {startCssStyle(mSpannableStringBuilder, 属性);} else if (tag.equalsIgnoreCase("strong")) {开始(mSpannableStringBuilder,新粗体());} else if (tag.equalsIgnoreCase("b")) {开始(mSpannableStringBuilder,新粗体());} else if (tag.equalsIgnoreCase("em")) {开始(mSpannableStringBuilder,新斜体());} else if (tag.equalsIgnoreCase("cite")) {开始(mSpannableStringBuilder,新斜体());} else if (tag.equalsIgnoreCase("dfn")) {开始(mSpannableStringBuilder,新斜体());} else if (tag.equalsIgnoreCase("i")) {开始(mSpannableStringBuilder,新斜体());} else if (tag.equalsIgnoreCase("big")) {开始(mSpannableStringBuilder,新的大());} else if (tag.equalsIgnoreCase("small")) {开始(mSpannableStringBuilder,新的小());} else if (tag.equalsIgnoreCase("font")) {startFont(mSpannableStringBuilder, 属性);} else if (tag.equalsIgnoreCase("blockquote")) {startBlockquote(mSpannableStringBuilder, 属性);} else if (tag.equalsIgnoreCase("tt")) {开始(mSpannableStringBuilder,新等宽());} else if (tag.equalsIgnoreCase("a")) {startA(mSpannableStringBuilder, 属性);} else if (tag.equalsIgnoreCase("u")) {开始(mSpannableStringBuilder,新的下划线());} else if (tag.equalsIgnoreCase("del")) {开始(mSpannableStringBuilder,新删除线());} else if (tag.equalsIgnoreCase("s")) {开始(mSpannableStringBuilder,新删除线());} else if (tag.equalsIgnoreCase("strike")) {开始(mSpannableStringBuilder,新删除线());} else if (tag.equalsIgnoreCase("sup")) {开始(mSpannableStringBuilder,新的超级());} else if (tag.equalsIgnoreCase("sub")) {开始(mSpannableStringBuilder,新的子());} else if (tag.length() == 2 &&Character.toLowerCase(tag.charAt(0)) == 'h' &&tag.charAt(1) >= '1' &&tag.charAt(1) <= '6') {startHeading(mSpannableStringBuilder, 属性, tag.charAt(1) - '1');} else if (tag.equalsIgnoreCase("img")) {startImg(mSpannableStringBuilder, 属性, mImageGetter);} else if (mTagHandler != null) {mTagHandler.handleTag(true, tag, mSpannableStringBuilder, mReader);}}

其中包含所有受支持的 HTML 标记.这个列表可能会在未来的版本中发生变化(它从我的原始答案中改变),但您可以自己挖掘源代码以在以后的版本中找到它.有了上面的代码,这是目前支持的列表:

brpul李div跨度强的b时间引用东风一世大的小的字体块引用tt一个你德尔s罢工子支持图像h1h2h3h4h5h6

其他方法涵盖了支持的属性(在 中,href 是一个属性):


img:

src


字体:

颜色脸

size 显然不受支持.


a:

href


p、ul 和 div 调用 startBlockElement,它给出了一个属性:

文本对齐

特别值得注意的是支持的对齐变量.

  • 中心 - 标准且不言自明
  • 开始 - 左对齐
  • end - 右对齐

开始和结束在 RTL 布局中可能会颠倒 - 我还没有测试过.


span 和 p,以及 li 调用 startCssStyle,它可以访问 以下 style 属性:

文本装饰背景颜色或背景颜色

text-decoration 似乎仅限于 line-through.

I need an official list of supported HTML tags on Android TextView. I'm using textView.setText(Html.fromHtml(label)); but I don't know which tags are supported.

解决方案

Note:

This targets API 27. Earlier versions are NOT guaranteed to support the tags seen in this list, and same for later ones (they could be removed). See the equivalent class for the applicable API versions for the applicable list.


It seems these aren't documented anywhere (correction, 2021: no longer the case), and there isn't a concrete list of when tags are added (2021: this still appears to be the case). I figured the HTML tags would need to be declared somewhere, if not in the docs, at least in the code. Fortunately, Android's HTML parsing is straight-forward enough to easily understand the relevant bits without dumpster-diving too much.

For future versions: you can either use IntelliJ or some other IDE to explore the source code of Html.java, or you can always go to the AOSP site or the equivalent GitHub repository. Using an IDE is potentially the easiest option.

Html#fromHtml(String, int) calls Html#fromHtml(String, Int, ImageGetter, TagHandler. The last method creates a HtmlToSpannedConverter, and returns the result of the conversion. I dug into that code, and I found this method:

private void handleStartTag(String tag, Attributes attributes) {

    if (tag.equalsIgnoreCase("br")) {
        // We don't need to handle this. TagSoup will ensure that there's a </br> for each <br>
        // so we can safely emit the linebreaks when we handle the close tag.
    } else if (tag.equalsIgnoreCase("p")) {
        startBlockElement(mSpannableStringBuilder, attributes, getMarginParagraph());
        startCssStyle(mSpannableStringBuilder, attributes);
    } else if (tag.equalsIgnoreCase("ul")) {
        startBlockElement(mSpannableStringBuilder, attributes, getMarginList());
    } else if (tag.equalsIgnoreCase("li")) {
        startLi(mSpannableStringBuilder, attributes);
    } else if (tag.equalsIgnoreCase("div")) {
        startBlockElement(mSpannableStringBuilder, attributes, getMarginDiv());
    } else if (tag.equalsIgnoreCase("span")) {
        startCssStyle(mSpannableStringBuilder, attributes);
    } else if (tag.equalsIgnoreCase("strong")) {
        start(mSpannableStringBuilder, new Bold());
    } else if (tag.equalsIgnoreCase("b")) {
        start(mSpannableStringBuilder, new Bold());
    } else if (tag.equalsIgnoreCase("em")) {
        start(mSpannableStringBuilder, new Italic());
    } else if (tag.equalsIgnoreCase("cite")) {
        start(mSpannableStringBuilder, new Italic());
    } else if (tag.equalsIgnoreCase("dfn")) {
        start(mSpannableStringBuilder, new Italic());
    } else if (tag.equalsIgnoreCase("i")) {
        start(mSpannableStringBuilder, new Italic());
    } else if (tag.equalsIgnoreCase("big")) {
        start(mSpannableStringBuilder, new Big());
    } else if (tag.equalsIgnoreCase("small")) {
        start(mSpannableStringBuilder, new Small());
    } else if (tag.equalsIgnoreCase("font")) {
        startFont(mSpannableStringBuilder, attributes);
    } else if (tag.equalsIgnoreCase("blockquote")) {
        startBlockquote(mSpannableStringBuilder, attributes);
    } else if (tag.equalsIgnoreCase("tt")) {
        start(mSpannableStringBuilder, new Monospace());
    } else if (tag.equalsIgnoreCase("a")) {
        startA(mSpannableStringBuilder, attributes);
    } else if (tag.equalsIgnoreCase("u")) {
        start(mSpannableStringBuilder, new Underline());
    } else if (tag.equalsIgnoreCase("del")) {
        start(mSpannableStringBuilder, new Strikethrough());
    } else if (tag.equalsIgnoreCase("s")) {
        start(mSpannableStringBuilder, new Strikethrough());
    } else if (tag.equalsIgnoreCase("strike")) {
        start(mSpannableStringBuilder, new Strikethrough());
    } else if (tag.equalsIgnoreCase("sup")) {
        start(mSpannableStringBuilder, new Super());
    } else if (tag.equalsIgnoreCase("sub")) {
        start(mSpannableStringBuilder, new Sub());
    } else if (tag.length() == 2 &&
            Character.toLowerCase(tag.charAt(0)) == 'h' &&
            tag.charAt(1) >= '1' && tag.charAt(1) <= '6') {
        startHeading(mSpannableStringBuilder, attributes, tag.charAt(1) - '1');
    } else if (tag.equalsIgnoreCase("img")) {
        startImg(mSpannableStringBuilder, attributes, mImageGetter);
    } else if (mTagHandler != null) {
        mTagHandler.handleTag(true, tag, mSpannableStringBuilder, mReader);
    }
}

Which does contain all of the supported HTML tags. This list might change in future versions (it did from the original answer I had), but you can dig through the source yourself to find it in later versions. With the above code, this is the currently supported list:

br
p
ul
li
div
span
strong
b
em
cite
dfn
i
big
small
font
blockquote
tt
a
u
del
s
strike 
sub
sup
img 
h1
h2
h3
h4
h5
h6

Further methods cover supported attributes (in <a href="">, href is an attribute):


img:

src


font:

color
face

size is apparently not supported.


a:

href


p, ul, and div calls startBlockElement, which gives one attrib:

text-align

Something special worth noting about this is the supported align variables.

  • center - standard and self-explanatory
  • start - aligns left
  • end - aligns right

start and end might be inverted in RTL layouts - I haven't tested.


span and p, and li calls startCssStyle, which gives access to the following style attributes:

text-decoration
background-color or background
color

text-decoration seems to be limited to line-through.

这篇关于Android TextView 上支持的 html 标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆