zoukankan      html  css  js  c++  java
  • textview 显示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.class, new StyleSpan(Typeface.BOLD)); 
    } else if (tag.equalsIgnoreCase("b")) { 
    end(mSpannableStringBuilder, Bold.class, new StyleSpan(Typeface.BOLD)); 
    } else if (tag.equalsIgnoreCase("strong")) { 
    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); 


    通过源码可以看到,除了默认的一些标签,其还支持自定义标签;看下面代码: 
    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, null, new MxgsaTagHandler(this))); 
    tView.setClickable(true); 
    tView.setMovementMethod(LinkMovementMethod.getInstance()); 

  • 相关阅读:
    数据库从别的数据库查询一张表在插入到新的数据库里面
    html5 学习随笔 1
    .net MVC 学习笔记 (一)
    Html5 本地存储
    .net MVC 学习笔记 (二)
    蝙蝠侠解救罗宾的问题
    求职的第一面Harman
    求职第七面——烽火通讯
    求职的第二面—Samsung
    求职第六面——瑞星微电子
  • 原文地址:https://www.cnblogs.com/awkflf11/p/5502605.html
Copyright © 2011-2022 走看看