关于TextView 的富文本实现方式,有2中,一种使用Html来做,一种是使用SpannableString;
SpannableString太麻烦了,这里有参考:
http://www.chawenti.com/articles/16016.html
关于 TextView使用Html,可以参考 这篇blog
http://blog.csdn.net/johnsonblog/article/details/7741972#comments
String类是CharSequence的子类,在CharSequence子类中有一个接口Spanned,即类似html的带标记的文本,我们可以用它来在TextView中显示html。但在上面Android源码注释中有提及TextView does not accept HTML-like formatting。
android.text.Html类共提供了三个方法,可以到Android帮助文档查看。
public static Spanned fromHtml (String source)
public static Spanned fromHtml (String source, Html.ImageGetter imageGetter, Html.TagHandler tagHandler)
public static String toHtml (Spanned text)
经常使用的是第一个方法:
TextView tv=(TextView)findViewById(R.id.textView1);
String html="<html><head><title>TextView
使用HTML</title></head><body><p><strong>强
调</strong></p><p><em>斜体</em></p>"
+"<p><a href=\"http://www.dreamdu.com
/xhtml/\">超链接HTML入门</a>学习HTML!<
/p><p><font color=\"#aabb00\">颜色1"
+"</p><p><font color=\"#00bbaa
\">颜色2</p><h1>标题1</h1><h3>标题2<
/h3><h6>标题3</h6><p>大于>小于<</p><p>" +
"下面是网络图片</p><img src=\"http://avatar.csdn.net/0/3/8/2_zhang957411207.jpg\"/></body></html>";
tv.setMovementMethod(ScrollingMovementMethod.getInstance());//滚动
tv.setText(Html.fromHtml(html));
要实现图片的显示需要使用Html.fromHtml的另外第二个重构方法:
public static Spanned fromHtml (String source, Html.ImageGetterimageGetter, Html.TagHandler tagHandler)
其中Html.ImageGetter是一个接口,我们要实现此接口,在它的getDrawable(String source)方法中返回图片的Drawable对象才可以。
ImageGetter imgGetter = new Html.ImageGetter() {
public Drawable getDrawable(String source) {
Drawable drawable = null;
URL url;
try {
url = new URL(source);
drawable = Drawable.createFromStream(url.openStream(), ""); //获取网路图片
} catch (Exception e) {
return null;
}
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable
.getIntrinsicHeight());
return drawable;
}
};
这里主要是实现了Html.ImageGetter接口,通过图片的URL地址获取相应的Drawable实例。
上面介绍的是显示网络上的图片,但如何显示本地的图片呢:
ImageGetter imgGetter = new Html.ImageGetter() {
public Drawable getDrawable(String source) {
Drawable drawable = null;
drawable = Drawable.createFromPath(source); //显示本地图片
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable
.getIntrinsicHeight());
return drawable;
}
};
只需将source改为本地图片的路径便可,在这里我使用的是:
String source;
source=getFilesDir()+"/ic_launcher.png";
这里主要讲一种场合的使用,来源
http://www.jb51.net/article/36643.htm
然而,有一种场合,默认支持的标签可能不够用。比如,我们需要在textView中点击某种链接,返回到应用中的某个界面,而不仅仅是网络连接,如何实现?
Html类中有一个接口类处理点击标签的处理的:
/**
* Is notified when HTML tags are encountered that the parser does
* not know how to interpret.
*/
public static interface TagHandler {
/**
* This method will be called whenn the HTML parser encounters
* a tag that it does not know how to interpret.
*/
public void handleTag(boolean opening, String tag,
Editable output, XMLReader xmlReader);
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.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.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);
}
}
如果不是默认的标签,会调用mTagHandler的handleTag方法。所以,我们可以实现此接口,来解析自己定义的标签类型。
自定义一个<game>标签,实现接口
public class GameTagHandler implements TagHandler {
private int startIndex = 0;
private int stopIndex = 0;
@Override
public void handleTag(boolean opening, String tag, Editable output,
XMLReader xmlReader) {
if (tag.toLowerCase().equals("game")) {
if (opening) {
startGame(tag, output, xmlReader);
} else {
endGame(tag, output, xmlReader);
}
}
}
public void startGame(String tag, Editable output, XMLReader xmlReader) {
startIndex = output.length();
}
public void endGame(String tag, Editable output, XMLReader xmlReader) {
stopIndex = output.length();
output.setSpan(new GameSpan(), startIndex, stopIndex,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
private class GameSpan extends ClickableSpan implements OnClickListener {
@Override
public void onClick(View v) {
// 跳转某页面 ,自己实现跳转的动作,就可以点击TextView中的指定文字进行自定义的动作的了
}
}
然后在工程中调用方法:
textView.setText(Html.fromHtml(“点击<game>这里</game>跳转到游戏”,null, new GameTagHandler()));
textView.setClickable(true);
textView.setMovementMethod(LinkMovementMethod.getInstance());