• Android中Textview显示带html文本一【HTML标签】


    现在网络的繁盛时代,光文字是不能满足人们的胃口的,图片,flash,音频,视频就成为浏览网页的主流显示,在手机上也一样。在手机上显示从网络端获取的数据显示,大家很自然的想起两种方式,一种就是webview,一种就是TextView。当然webView直接显示html页面就行了,我主要说的TextView显示html内容。

    首先,说下TextView到底支持那些标签呢,通过对源码的查看,发现Textview可以解析一部分html标签,如:

    <a href="...">
    <b>
    <big>
    <blockquote>
    <br>
    <cite>
    <dfn>
    <div align="...">
    <em>
    <font size="..." color="..." face="...">
    <h1>
    <h2>
    <h3>
    <h4>
    <h5>
    <h6>
    <i>
    <img src="...">
    <p>
    <small>
    <strike>
    <strong>
    <sub>
    <sup>
    <tt>
    <u>

    大家想究其根本可以查看android.text.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);
            }
        }

        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("em")) {
                end(mSpannableStringBuilder, Bold.classnew StyleSpan(Typeface.BOLD));
            } else if (tag.equalsIgnoreCase("b")) {
                end(mSpannableStringBuilder, Bold.classnew StyleSpan(Typeface.BOLD));
            } else if (tag.equalsIgnoreCase("strong")) {
                end(mSpannableStringBuilder, Italic.classnew StyleSpan(Typeface.ITALIC));
            } else if (tag.equalsIgnoreCase("cite")) {
                end(mSpannableStringBuilder, Italic.classnew StyleSpan(Typeface.ITALIC));
            } else if (tag.equalsIgnoreCase("dfn")) {
                end(mSpannableStringBuilder, Italic.classnew StyleSpan(Typeface.ITALIC));
            } else if (tag.equalsIgnoreCase("i")) {
                end(mSpannableStringBuilder, Italic.classnew StyleSpan(Typeface.ITALIC));
            } else if (tag.equalsIgnoreCase("big")) {
                end(mSpannableStringBuilder, Big.classnew RelativeSizeSpan(1.25f));
            } else if (tag.equalsIgnoreCase("small")) {
                end(mSpannableStringBuilder, Small.classnew RelativeSizeSpan(0.8f));
            } else if (tag.equalsIgnoreCase("font")) {
                endFont(mSpannableStringBuilder);
            } else if (tag.equalsIgnoreCase("blockquote")) {
                handleP(mSpannableStringBuilder);
                end(mSpannableStringBuilder, Blockquote.classnew 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.classnew UnderlineSpan());
            } else if (tag.equalsIgnoreCase("sup")) {
                end(mSpannableStringBuilder, Super.classnew SuperscriptSpan());
            } else if (tag.equalsIgnoreCase("sub")) {
                end(mSpannableStringBuilder, Sub.classnew 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);
            }
        }

    通过源码可以看到,除了默认的一些标签,其还支持自定义标签;看下面代码:

    else if (mTagHandler != null) {
                mTagHandler.handleTag(false, tag, mSpannableStringBuilder, mReader);
            }

    系统会调用mTagHandler的handleTag方法。所以,我们可以实现此接口,来解析自己定义的标签类型。

    具体的,自己可以看一下下面实例:

    package com.mxgsa.tvimg;

    import org.xml.sax.XMLReader;

    import android.content.Context;
    import android.content.Intent;
    import android.text.Editable;
    import android.text.Html.TagHandler;
    import android.text.Spanned;
    import android.text.style.ClickableSpan;
    import android.view.View;
    import android.view.View.OnClickListener;

    public class MxgsaTagHandler implements TagHandler{
        private int sIndex = 0;  
        private  int eIndex=0;
        private final Context mContext;
        
        public MxgsaTagHandler(Context context){
            mContext=context;
        }
        
        public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {
            // TODO Auto-generated method stub
            if (tag.toLowerCase().equals("mxgsa")) {
                if (opening) {
                    sIndex=output.length();
                }else {
                    eIndex=output.length();
                    output.setSpan(new MxgsaSpan(), sIndex, eIndex, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                }
            }
        }
        private class MxgsaSpan extends ClickableSpan implements OnClickListener{
            @Override
            public void onClick(View widget) {
                // TODO Auto-generated method stub
                
    //具体代码,可以是跳转页面,可以是弹出对话框,下面是跳转页面
                mContext.startActivity(new Intent(mContext,MainActivity.class));
            }
        }

    }

    调用页面:

    package com.mxgsa.tvimg;

    import android.app.Activity;
    import android.os.Bundle;
    import android.text.Html;
    import android.text.method.LinkMovementMethod;
    import android.widget.TextView;

    public class MxgsaActivity extends Activity{

        private TextView tView;

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.mxgsa_activity);
            findControl();
            setData();
        }

        private void findControl() {
            tView = (TextView) findViewById(R.id.tvImage);
        }

        private void setData() {
            // TODO Auto-generated method stub
            final String sText = "测试自定义标签:<br><h1><mxgsa>测试自定义标签</mxgsa></h1>";
            tView.setText(Html.fromHtml(sText, nullnew MxgsaTagHandler(this)));
            tView.setClickable(true);
            tView.setMovementMethod(LinkMovementMethod.getInstance());
        }

        

    }

    下篇将会讲带图片的html文本显示!

     好久没有查看博客了,很多人评论要求代码,需要代码的请参考mengxg技术博客

    欢迎关注我的技术博客:mengxg技术博客
  • 相关阅读:
    需求分析与系统设计(二)阅读笔记
    阅读笔记:需求分析与系统设计(一)
    css方法div固定在网页底部
    阅读笔记:软件需求十步走(三)
    剑指offer 二维数组中的查找
    剑指offer 替换空格
    剑指offer 重建二叉树
    git常用操作
    关于 IO的同步异步间要描述
    svn-代码回滚
  • 原文地址:https://www.cnblogs.com/mxgsa/p/2760256.html
Copyright © 2020-2023  润新知