Html类位于Android.text.Html中,该类主要用来格式html格式的文本,像浏览器一样对html标签进行解析并渲染输出,但并不是所有的标签都被支持;不过我们可以实现Html.TagHandler这个接口来自我解析;
内部类:
interface Html.ImageGetter
用于检索HTML中的<img>标签,如果实现了这个接口,当解析到<img>标签时会回调ImageGetter的getDrawable(String source)方法,并返回一个Drawable对象,该方法的参数为<img>标签的src属性的值;
interface Html.TagHandler
用于通知当解析器遇到无法识别的标签时该作出何种处理;
公共方法:
public static Spanned fromHtml(String source)
返回通过TagSoup解析器解析之后的并可直接显示的文本(TagSoup是一个Java开发符合SAX的HTML解析器授权协议);
public static Spanned fromHtml(String source, Html.ImageGetter imageGetter, TagHandler tagHandler)
该方法与fromHtml(String source)方法一致,不过当解析到<img>标签时会触发注册的imageGetter对象来进行处理,而如果解析到无法识别的标签时则会触发tagHandler对象来处理;
public static String toHtml(Spanned text)
该方法可以理解为fromHtml()的可逆函数,将Spanned类型的文本还原为HTML文本;
那么Html类中的方法已经大致的了解了,接着我们则来看看Html支持了那些标签呢,我们一起去看看Html类的源码;
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 emite the linebreaks when we handle the close tag. } else if (tag.equalsIgnoreCase("p")) { handleP(mSpannableStringBuilder); } else if (tag.equalsIgnoreCase("div")) { handleP(mSpannableStringBuilder); } 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")) { handleP(mSpannableStringBuilder); start(mSpannableStringBuilder, new Blockquote()); } 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("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') { handleP(mSpannableStringBuilder); start(mSpannableStringBuilder, new Header(tag.charAt(1) - '1')); } else if (tag.equalsIgnoreCase("img")) { startImg(mSpannableStringBuilder, attributes, mImageGetter); } else if (mTagHandler != null) { mTagHandler.handleTag(true, tag, mSpannableStringBuilder, mReader); } } private void handleEndTag(String tag) { if (tag.equalsIgnoreCase("br")) { handleBr(mSpannableStringBuilder); } else if (tag.equalsIgnoreCase("p")) { handleP(mSpannableStringBuilder); } else if (tag.equalsIgnoreCase("div")) { handleP(mSpannableStringBuilder); } else if (tag.equalsIgnoreCase("strong")) { end(mSpannableStringBuilder, Bold.class, new StyleSpan(Typeface.BOLD)); } else if (tag.equalsIgnoreCase("b")) { end(mSpannableStringBuilder, Bold.class, new StyleSpan(Typeface.BOLD)); } else if (tag.equalsIgnoreCase("em")) { end(mSpannableStringBuilder, Italic.class, new StyleSpan(Typeface.ITALIC)); } else if (tag.equalsIgnoreCase("cite")) { end(mSpannableStringBuilder, Italic.class, new StyleSpan(Typeface.ITALIC)); } else if (tag.equalsIgnoreCase("dfn")) { end(mSpannableStringBuilder, Italic.class, new StyleSpan(Typeface.ITALIC)); } else if (tag.equalsIgnoreCase("i")) { end(mSpannableStringBuilder, Italic.class, new StyleSpan(Typeface.ITALIC)); } else if (tag.equalsIgnoreCase("big")) { end(mSpannableStringBuilder, Big.class, new RelativeSizeSpan(1.25f)); } else if (tag.equalsIgnoreCase("small")) { end(mSpannableStringBuilder, Small.class, new RelativeSizeSpan(0.8f)); } else if (tag.equalsIgnoreCase("font")) { endFont(mSpannableStringBuilder); } else if (tag.equalsIgnoreCase("blockquote")) { handleP(mSpannableStringBuilder); end(mSpannableStringBuilder, Blockquote.class, new QuoteSpan()); } else if (tag.equalsIgnoreCase("tt")) { end(mSpannableStringBuilder, Monospace.class, new TypefaceSpan("monospace")); } else if (tag.equalsIgnoreCase("a")) { endA(mSpannableStringBuilder); } else if (tag.equalsIgnoreCase("u")) { end(mSpannableStringBuilder, Underline.class, new UnderlineSpan()); } else if (tag.equalsIgnoreCase("sup")) { end(mSpannableStringBuilder, Super.class, new SuperscriptSpan()); } else if (tag.equalsIgnoreCase("sub")) { end(mSpannableStringBuilder, Sub.class, new SubscriptSpan()); } else if (tag.length() == 2 && Character.toLowerCase(tag.charAt(0)) == 'h' && tag.charAt(1) >= '1' && tag.charAt(1) <= '6') { handleP(mSpannableStringBuilder); endHeader(mSpannableStringBuilder); } else if (mTagHandler != null) { mTagHandler.handleTag(false, tag, mSpannableStringBuilder, mReader); } }
通过查看Html源码我们得知支持的标签如下:
<a href="">标签的href属性用于指定超连接目标的URL;实例——<a href="http://www.csdn.net/">SCDN</a>;
<b>标签呈现粗体文本效果;实例——<b>CSDN.NET - 全球最大中文IT社区</b>
<big>标签呈现大号字体效果;
<blockquote>在<blockquote>与</blockquote>之间的所有文本都会从文本中分离处理,经常会在左、右两边进行缩进;
<br>标签用于换行;
<cite>在标签内的文本将以斜体显示;
<dfn>在标签内的文本将以斜体显示;
<div align="">标签的align属性规定div元素的内容水平对齐方式;实例居中对齐——<div align="center">CSDN.NET - 全球最大中文IT社区</div>
<em>标签可显示强调的文本;
<font size="" color="" face="">规定文本的字体、字体尺寸、字体颜色;实例——<font size="10" color="red" face="verdana">CSDN.NET - 全球最大中文IT社区</font>
<h1>、<h2>、<h3>、<h4>、<h5>、<h6>标签显示不同大小的文本;
<i>标签显示斜体文本效果;
<img src="">标签用于显示一张图片,src属性则为图片的路径;
<small>标签呈现小号字体效果;
<strike>标签可显示加删除线的文本;
<strong>标签和<em>标签一样,用于强调文本,但它的强调的程度更强一些;
<sub>标签可显示下标文本;
<sup>标签可显示上标文本;
<tt>标签显示打字机文本;
<u>标签可显示下划线文本;
在源码中我们看到除默认支持的一些标签以外,还支持自定义的标签,源码如下:
else if (mTagHandler != null) { mTagHandler.handleTag(true, tag, mSpannableStringBuilder, mReader); }
即如果我们实现了了TagHandler接口时则会回调mTagHandler的handleTag()方法,所以可以进行定义我们自己的标签并对其进行相应的处理;