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,如自定义一些背景前景,实现动态图片的显示等都是可以的,有需要时可以研究研究。

原文地址:https://www.cnblogs.com/qiengo/p/2519166.html