现在网络的繁盛时代,光文字是不能满足人们的胃口的,图片,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()); 

textview 显示html方法解析的更多相关文章

  1. 我的Android进阶之旅------&amp;gt; Android在TextView中显示图片方法

    面试题:请说出Android SDK支持哪些方式显示富文本信息(不同颜色.大小.并包括图像的文本信息).并简要说明实现方法. 答案:Android SDK支持例如以下显示富文本信息的方式. 1.使用T ...

  2. Android中用TextView显示大量文字的方法

    最近学习Android中,试着实现一个简单的显示新闻Demo的时候,遇到了一个问题:一条新闻的内容文字很多,放在TextView上面超出屏幕了,怎么破? 查了一下资料,找到了两种方法实现: 1. 只用 ...

  3. TextView 显示内容时出现 ArrayIndexOutOfBoundsException 的解决方法(Android 4.1)

    很久以前做的表情输入及显示,用的系统的SpannableString,完成后的代码在其他版本的Android手机上没有问题,但是在在4.1和4.1.1的手机上显示时,有概率出现程序崩溃的问题. 下面是 ...

  4. Python的方法解析顺序(MRO)[转]

    本文转载自: http://hanjianwei.com/2013/07/25/python-mro/ 对于支持继承的编程语言来说,其方法(属性)可能定义在当前类,也可能来自于基类,所以在方法调用时就 ...

  5. 文件_ _android从资源文件中读取文件流并显示的方法

    ======== 1   android从资源文件中读取文件流并显示的方法. 在android中,假如有的文本文件,比如TXT放在raw下,要直接读取出来,放到屏幕中显示,可以这样: private ...

  6. Android项目实战(十四):TextView显示html样式的文字

    项目需求: TextView显示一段文字,格式为:(消息个数,不确定)条消息 这段文字中名字和数字的长度是不确定的,还要求名字和数字各自有各自的颜色. 一开始我想的是用(转) SpannableStr ...

  7. Android设置TextView显示一行或多行

    在listView的item中或者是特殊的业务需求中,会要求TextView的内容不完全显示,只有通过一个指定的操作后才显示所有的,比如说一个按钮或者是其它的什么控件. 要想实现这个效果并不难,只要控 ...

  8. sqlalchemy mark-deleted 和 python 多继承下的方法解析顺序 MRO

    sqlalchemy mark-deleted 和 python 多继承下的方法解析顺序 MRO 今天在弄一个 sqlalchemy 的数据库基类的时候,遇到了跟多继承相关的一个小问题,因此顺便看了一 ...

  9. iOS 详解NSXMLParser方法解析XML数据方法

    前一篇文章已经介绍了如何通过URL从网络上获取xml数据.下面介绍如何将获取到的数据进行解析. 下面先看看xml的数据格式吧! <?xml version="1.0" enc ...

随机推荐

  1. 戏说HTML5

    如果有非技术人员问你,HTML5是什么,你会怎么回答? 新的HTML规范... 给浏览器提供了牛逼能力,干以前不能干的事...(确切地说应该是给浏览器规定了许多新的接口标准,要求浏览器实现牛逼的功能. ...

  2. 【原创】自己动手写工具----XSmartNote [Beta 1.0]

    一.背景 有个朋友是在他们单位的市场部,手里的策划文案以及PPT,少则数百,多则上千,多年下来也是一笔不可小觑的财富,每一次新的策划都可以从以往的文案或PPT中“拿来主义”,有着很好的借鉴意义,但是这 ...

  3. CSS3--overflow属性

    overflow:当内容溢出元素框时发生的事情: overflow:默认,内容不会裁剪,会呈现在元素框之外: overflow:hidden:内容会被裁剪,并且其余部分是不可见的(清除浮动) over ...

  4. Python实现对文件夹内文本文件递归查找

    平台:Win7 64 bit,IDLE Python 3.4.0 经常有这样的需求:在一个文本文件里查找特定字符串,这很好实现,用任何文本查看工具几乎都可以做到.而有的时候,想查找一个文件夹下的所有文 ...

  5. [置顶]PADS PCB功能使用技巧系列之NO.002- 如何走差分线?

    差分信号在高速电路设计中应用越来越广泛,如USB.HDMI.PCI.DDR*等,承载差分信号的差分线主要优势有:抗干扰能力强,能有效抑制EMI.时序定位精确等,对于PCB工程师来说,最关注的是如何确保 ...

  6. TinyFrame升级之十:WCF Rest Service注入IOC的心

    由于在实际开发中,Silverlight需要调用WebService完成数据的获取,由于之前我们一直采用古老的ASMX方式,生成的代理类不仅难以维护,而且自身没有提供APM模式的调用方式,导致在Sin ...

  7. 字体Unicode编码

    客专家福利     有奖试读&征文——我们在互联网上奋斗的故事      10月推荐文章汇总      加入“技术热心人”,赢丰厚奖品 html-中文字体在CSS中的显示(Unicode编码) ...

  8. supervisor 配置

    1. 生成配置文件$ echo_supervisord_conf > /etc/supervisord.conf 2.修改配置文件vi /etc/supervisord.conf找到[inclu ...

  9. Winform中如何实现父窗体传递数据到子窗体并刷新子窗体

    原理:利用委托和事件,本文将以图文并茂的例子讲述,告诉我们So Easy --------------------------------------------------------------- ...

  10. HDU 4292 Food

    Food Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...