zoukankan      html  css  js  c++  java
  • 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删掉,这样就可以执行到了。唉,踩了个大坑。

  • 相关阅读:
    拉格朗日乘数法
    凸优化
    2018-2-13-安装visualStudio-出现-cant-install-Microsoft.TeamFoundation.OfficeIntegration.Resources...
    2019-11-9-win10-支持默认把触摸提升-Pointer-消息
    2019-7-1-Roslyn-让编译时候-Message-内容默认输出
    2019-8-31-win2d-通过-CanvasActiveLayer-画出透明度和裁剪
    2019-10-4-C#-极限压缩-dotnet-core-控制台发布文件
    2019-8-31-dotnet-获取指定进程的输入命令行
    2019-8-30-PowerShell-通过-WMI-获取系统安装的驱动
    2018-8-10-VisualStudio-2017-项目格式-自动生成版本号
  • 原文地址:https://www.cnblogs.com/wangyuehome/p/9989213.html
Copyright © 2011-2022 走看看