android textiew自定义ClickableSpan无效问题

我们有个需求,需要将一段文本中的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删掉,这样就可以执行到了。唉,踩了个大坑。

 

posted on 2018-11-20 15:28  取悦  阅读(3982)  评论(0编辑  收藏  举报

导航