一般我们在项目中会有这样的需求,要求文本中超链接显示出来并点击可以跳转到对应的web网页界面。而TextView本身就自带这样的属性,在xml布局文件里设置android:autoLink="web"这行代码就可以把web链接显示出来。但是经测试,发现原生并不能达到我们项目中的预期项目,那么就需要我们重写来达到我们的预期效果。下面是效果图,把文本的超链接显示出来并可以设置点击事件。
那么我们现在来看看怎么实现,主要的封装了2个类,LinkedUtils类:
public class LinkedUtils {
private static Pattern URL_PATTERN_DEFAULT= Pattern.compile("((http|https):\\/\\/)?([a-zA-Z0-9-]+\\.){1,5}(com|cn|net|org|hk|tw)((\\/(\\w|-)+(\\.([a-zA-Z]+))?)+)?(\\/)?(\\??([\\.%:a-zA-Z0-9_-]+=[#\\.%:a-zA-Z0-9_-]+(&)?)+)?");
public static Spannable String getUrlSpan(String txt) {
SpannableString value = SpannableString.valueOf(txt);
Linkify.addLinks(value, LinkedUtils.URL_PATTERN_DEFAULT,"");
URLSpan[] urlSpans = value.getSpans(0, value.length(), URLSpan.class);
for(URLSpan urlSpan : urlSpans) {
int start = value.getSpanStart(urlSpan);
int end = value.getSpanEnd(urlSpan);
value.removeSpan(urlSpan);
value.setSpan(newUrlLinkSpan(urlSpan.getURL()), start, end, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);}
return value;
}
/**
* 文字链接处理
*/
public static class UrlLinkSpanextendsClickableSpan {
private String mUrl;
private int highColor=0xff576b95;
publicUrlLinkSpan(String url) {
mUrl= url;
}
@Override
public void onClick(View widget) {
Toast.makeText(widget.getContext(),"天气真好:》》",Toast.LENGTH_LONG).show();//这里可以操作获取的超链接
}
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setColor(highColor);
ds.setUnderlineText(false);
}}}
另一个类是为了解决文本长按时和点击链接触发的冲突:
public class LinkMovementClickMethod extends LinkMovementMethod {
private long lastClickTime;
private static final longCLICK_DELAY=500l;
@Override
public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
int action = event.getAction();
if(action == MotionEvent.ACTION_UP||action == MotionEvent.ACTION_DOWN) {
int x = (int) event.getX();
int y = (int) event.getY();
x -= widget.getTotalPaddingLeft();
y -= widget.getTotalPaddingTop();
x += widget.getScrollX();
y += widget.getScrollY();
Layout layout = widget.getLayout();
int line = layout.getLineForVertical(y);
int off = layout.getOffsetForHorizontal(line, x);
ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);
if(link.length!=0) {
if(action == MotionEvent.ACTION_UP) {
if(System.currentTimeMillis() -lastClickTime
link[0].onClick(widget);
}
}else if(action == MotionEvent.ACTION_DOWN) {
Selection.setSelection(buffer,
buffer.getSpanStart(link[0]),
buffer.getSpanEnd(link[0]));
lastClickTime= System.currentTimeMillis();
}
return true;
}else{
Selection.removeSelection(buffer);
}}
return super.onTouchEvent(widget, buffer, event);
}
public static LinkMovementClickMethod getInstance(){
if(null==sInstance){
sInstance=newLinkMovementClickMethod();
}
return sInstance;
}
private static LinkMovementClickMethod sInstance;
}
之后有了这两个类就是我们的使用了,使用的方式十分简单:
tv_link.setMovementMethod(LinkMovementClickMethod.getInstance());
tv_link.setText(LinkedUtils.getUrlSpan(tv_link.getText().toString()));
只要这两行代码就可以实现效果了。