我们有个需求,需要将一段文本中的url跳转,替换成跳转我们app的某个页面。然后就开始搞,先自定义clickspan,在设置LinkMovementMethoid,
但是不管怎么搞就是不生效.
这是我的代码,红色部分是解决问题的方法:
/** * 拦截超链接 * @param tv */ private void interceptHyperLink(TextView tv,String content) { CharSequence text = Html.fromHtml(content); if (text instanceof Spannable) { int end = text.length(); Spannable spannable = (Spannable) text; URLSpan[] urlSpans = spannable.getSpans(0, end, URLSpan.class); SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(text); // 循环遍历并拦截 所有http://开头的链接 for (URLSpan uri : urlSpans) { String url = uri.getURL(); if (url.indexOf("http://") == 0 || url.indexOf("https://")==0) { CustomUrlSpan customUrlSpan = new CustomUrlSpan(getContext(), url, mIFragment); spannableStringBuilder.setSpan(customUrlSpan, spannableStringBuilder.getSpanStart(uri), spannableStringBuilder.getSpanEnd(uri), Spannable.SPAN_INCLUSIVE_INCLUSIVE); spannableStringBuilder.removeSpan(uri);//解决方法 } } tv.setText(spannableStringBuilder); tv.setMovementMethod(LinkMovementMethod.getInstance()); } }
后来仔细查看了下LinkMovementMethoid的代码,在ontouchevent方法里是这么写的。
@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) { link[0].onClick(widget); } else if (action == MotionEvent.ACTION_DOWN) { Selection.setSelection(buffer, buffer.getSpanStart(link[0]), buffer.getSpanEnd(link[0])); } return true; } else { Selection.removeSelection(buffer); } } return super.onTouchEvent(widget, buffer, event); }
绿色部分,当你点击textview中的某个urlspan时,LinkMovementMethoid会把所有的span都取出来放到一个数组里,然后执行第一个span的click事件,而我上面代码里设置的自定义的span,是在数组第二个的位置上,所以根本执行不到。我也纳闷明明已经setSpan了,为什么没有替换掉呢。
解决办法就是setSpan后把原来的urlspan删掉,这样就可以执行到了。唉,踩了个大坑。