Android use custom html tag in TextView
我们知道android的TextView控件支持一些简单的html富文本,如<br><font><u>等,但是具体是哪些标签呢?其实查看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("em")) { start(mSpannableStringBuilder, new Bold()); } else if (tag.equalsIgnoreCase("b")) { start(mSpannableStringBuilder, new Bold()); } else if (tag.equalsIgnoreCase("strong")) { 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); } }
通过上面的代码可以知道,TextView支持的标签有以下一些:
<br>换行,<p>段落,<div>,<em>强调,<b>加粗,<strong>重点强调,<cite>表示引用,<dfn>定义标签,<i>斜体,<big>大字体,<small>小字体,<font>字体,<blockquote>引用块,<tt>定义monospaced字体的文字,<a>链接,<u>下划线,<sup>上标,<sub>下标,<h>,<img>图片
上面的有些标签或是属性可能会没有用的,如font的size属性在源码里面没有做处理,因此size属性是没有用的,具体的可能还要尝试或是看看源码才知道。
下面是一个简单的实例
String source = "<font size='17sp' color='#FF0000'>font</font>" +
"<u>下划线</u>" +
"<h1>h1<h1>" +
"<big>big</big>"+
"<small>small</small>"+
"<strong>strong</strong>"+
"<i>斜体</i>"+
"<sup>上标</sup>"+
"<sub>下标</sub>";
text.setText(Html.fromHtml(source));
运行的效果如下:
除了上面的一些简单的字体变换外还可以实现在TextView中显示图片,表情即可以通过这种方式实现。
通过上面的源码可以看到,当解析发现有未识别的标签时会调用mTagHandler.handleTag(true, tag, mSpannableStringBuilder, mReader);
通过TagHandler接口我们可以自定义一些标签。
如下,我们自定义一个<mytag>的标签,实现了点击标签内容则显示一个Toast的事件(当然还可以实现其他一些事件)。
public class MyTagHandler implements TagHandler { int start; int stop; Context context; int color;
public MyTagHandler(Context context, int color) { this.context = context; this.color = color; } @Override public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) { if (tag.toLowerCase().equals("mytag")) { if (opening) { start = output.length(); } else { stop = output.length(); String content = output.subSequence(start, stop).toString(); output.setSpan(new MySpan(context, color, content), start, stop, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } } } class MySpan extends ClickableSpan implements OnClickListener { String content; int color; int type; Context context;
@Override public void updateDrawState(TextPaint ds) { ds.setColor(color);//设置颜色 ds.setUnderlineText(false);//是否显示下划线 } public MySpan(Context context, int color, String content) { this.context = context; this.color = color; this.content = content; } @Override public void onClick(View widget) { //添加点击事件 Toast.makeText(context, content, Toast.LENGTH_SHORT).show(); } } }
String source = "<u>下划线标签</u><mytag><big>自定义的标签</big></mytag><i>斜体</i>"; textview.setText(Html.fromHtml(source, null, new MyTagHandler(this, 0xFF4D8C4D))); textview.setMovementMethod(LinkMovementMethod.getInstance());
运行的效果如下,当点击"自定义标签"时会弹出一个Toast的提示。
上例中是实现了一个ClickableSpan以实现一个自定义的点击事件。还可以用android.text.style包里面的其他一些Span,如自定义一些背景前景,实现动态图片的显示等都是可以的,有需要时可以研究研究。