如果只是简单需要textview在显示时候将网址、邮件地址、电话号码识别出来并且带上超链接,只需要在xml将textview的属性添加一个autoLink="all"即可。但是如果希望在文字中定义更复杂的超链接,比如:点击特定文字后跳转到某个activity,则需要自定义Html类对于tag的解析方法。整个处理流程思路如下:
- TextView的文字使用带html tag的字符串,如:<a href=\"http://www.diandian.com\">android</a>其实并不难;
- 为要做除了网址链接、邮件链接、电话链接之外的超链接自己确定一个tag名字,加入到字符串中,如:<a href=\"http://www.diandian.com\">android</a>其实并不难<mention>哪里哪里</mention>;
- 自定义一个静态类,并且实现TagHandler接口,以识别自定义的tag类型
public static class LinkHandler implements TagHandler
{
private int startIndex = 0;
private int stopIndex = 0;
private Context ctx;
public LinkHandler(Context ctx)
{
super();
this.ctx=ctx;
}
//识别自定义标签的起始和终止位置
public void handleTag(boolean opening, String tag, Editable output,
XMLReader xmlReader) {
if(tag.toLowerCase().equals(" mention"))
{
if (opening) {
startTxt(tag, output, xmlReader);
} else {
endTxt(tag, output, xmlReader);
}
}
}
public void startTxt(String tag, Editable output, XMLReader xmlReader) {
startIndex = output.length();
}
public void endTxt(String tag, Editable output, XMLReader xmlReader) {
stopIndex = output.length();
output.setSpan(new TagSpan(output.toString().substring(startIndex,stopIndex)), startIndex, stopIndex,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
//继承ClickableSpan类自定义类TagSpan实现OnClickListener接口,以此决定被识别出来的链接被点击后做什么
private class TagSpan extends ClickableSpan implements OnClickListener {
String s;
public TagSpan(String s)
{
this.s=s;
}
@Override
public void onClick(View v) {
// 跳转某页面,将自定义tag对应的文字参数传递过去
NetActivity.pd.show();
getUid(s);
}
}
}
//在原始文本中提取@用户名 方式的文字出来,加上自定义的tag
public static String addTagsToString(String s)
{
//对@添加tag
Pattern p=Pattern.compile("@[\\S&&[^@]]+");
Matcher m=p.matcher(s);
while(m.find()){
s=s.replace(m.group(), "<mention>"+m.group()+"</mention>");
}
s="<a>"+s+"</a>"; //此处一定要在前后加上一个<a>标签,否则@用户名之后若还有文字,会被一起加入到mention标签之中,这个问题还没搞清楚是为什么,至少目前加上<a>标签后不会有问题
return s;
}
- 然后在activity中为textview设定文字
tv.setText(Html.fromHtml(addTagsToString(s),null,new LinkHandler(ctx)));
tv.setMovementMethod(LinkMovementMethod.getInstance());