textview使用SpanbleString导致ellsize的属性失效

11 篇文章 0 订阅
9 篇文章 0 订阅
这几天在开发一个图片混排带有超链的列表的时候,发现如果带有可点击的超链的textview以后,ellsize属性,即以省略号结尾的属性就不生效了,结果造成列表混乱,然后经过排查,刚开始以为是带图片的问题,后来发现并不是,而是下面这行代码的问题,只要设置这行代码就混乱了。
holder.connectInfo.setMovementMethod(LinkMovementMethod.getInstance());//不设置 没有点击事件

在查阅各种资料以后,发现这个问题的博客很少,现有的博客很多还是有点问题,不能根治,例如这个试着去重写textview,结果还是未果https://www.zhihu.com/question/52436308/answer/130588361   

,然后没办法,就试着去看

LinkMovementMethod的源码,然后发现
  1. if ((mMovement != null || onCheckIsTextEditor()) && isEnabled()  
  2.                 && mText instanceof Spannable && mLayout != null) {  
  3.             boolean handled = false;  
  4.   
  5.             if (mMovement != null) {  
  6.                 handled |= mMovement.onTouchEvent(this, (Spannable) mText, event);  
  7.             }  
  8.             final boolean textIsSelectable = isTextSelectable();  
  9.             if (touchIsFinished && mLinksClickable && mAutoLinkMask != 0 && textIsSelectable) {  
  10.                 // The LinkMovementMethod which should handle taps on links has not been installed  
  11.                 // on non editable text that support text selection.  
  12.                 // We reproduce its behavior here to open links for these.  
  13.                 ClickableSpan[] links = ((Spannable) mText).getSpans(getSelectionStart(),  
  14.                         getSelectionEnd(), ClickableSpan.class);  
  15.   
  16.                 if (links.length > 0) {  
  17.                     links[0].onClick(this);  
  18.                     handled = true;  
  19.                 }  
  20.             }  

它里面的部分就是通过setMovementMethod方法设置的对象。由于我们设置的是LinkMovementMethod的一个实例,继续打开LinkMovementMethod源码查看其中onTouchEvent的代码。

  1. if (mMovement != null) {  
  2.         handled |= mMovement.onTouchEvent(this, (Spannable) mText, event);  

  1. }

然后我试着将它的重要代码抽取出来,下面的代码代替它的

setMovementMethod方法,就可以了,完美解决混乱问题。
 //因为setMovementMethod会导致ellsize方法失效,图文混排错乱,所以这种方法保持正常
        holder.connectInfo.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                int action = event.getAction();

                TextView tv = (TextView) v;
                CharSequence text = tv.getText();
                if (text instanceof SpannedString) {
                    if (action == MotionEvent.ACTION_UP) {
                        int x = (int) event.getX();
                        int y = (int) event.getY();

                        x -= tv.getTotalPaddingLeft();
                        y -= tv.getTotalPaddingTop();

                        x += tv.getScrollX();
                        y += tv.getScrollY();

                        Layout layout = tv.getLayout();
                        int line = layout.getLineForVertical(y);
                        int off = layout.getOffsetForHorizontal(line, x);

                        ClickableSpan[] link = ((SpannedString)text).getSpans(off, off, ClickableSpan.class);
                        if (link.length != 0) {
                            link[0].onClick(tv);
                        } else {
                        }
                    }
                }

                return true;
            }
        });

下面还是上一下完整的代码吧,不然有的童鞋还是不理解

 /**
     * 设置超链
     */
    private void setSuperLinkContent(final ViewHolder holder, final String content, final Dynamic dynamicInfo) {
        String contents = "<font>" + content + "</font><img src='icon_link'> 查看详情";
        Html.ImageGetter imageGetter = new Html.ImageGetter() {
            @Override
            public Drawable getDrawable(String source) {
                if (source.endsWith("icon_link")) {
                    Drawable drawable = mContext.getResources().getDrawable(R.drawable.icon_link);
                    int fontH = (int) (mContext.getResources().getDimension(
                            R.dimen.publish_consult_hint) * 1.2);
                    int height = fontH;
                    int width = (int) ((float) drawable.getIntrinsicWidth() / (float) drawable
                            .getIntrinsicHeight()) * fontH;
                    if (width == 0) {
                        width = drawable.getIntrinsicWidth();
                    }
                    drawable.setBounds(0, 0, width, height);
                    return drawable;
                }
                return null;
            }
        };
        //底部提示语  快速咨询为超链
        SpannableString str = new SpannableString(Html.fromHtml(contents, imageGetter, null));
        str.setSpan(new ClickableSpan() {
            @Override
            public void updateDrawState(TextPaint ds) {
                super.updateDrawState(ds);         //设置文本的颜色
                ds.setColor(Color.parseColor("#2e84c6"));
                //超链接形式的下划线,false 表示不显示下划线,true表示显示下划线
                ds.setUnderlineText(false);
            }

            @Override
            public void onClick(View widget) {
                if (!TextUtils.isEmpty(dynamicInfo.getLinkUrl())) {
                    WebViewActivity.invoke(mContext, dynamicInfo.getLinkUrl());
                }
            }
        }, content.length(), content.length() + 6, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        holder.connectInfo.setText(str);
//        holder.connectInfo.setMovementMethod(LinkMovementMethod.getInstance());//不设置 没有点击事件
        holder.connectInfo.setHighlightColor(Color.TRANSPARENT); //设置点击后的颜色为透明

        //因为setMovementMethod会导致ellsize方法失效,图文混排错乱,所以这种方法保持正常
        holder.connectInfo.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                int action = event.getAction();

                TextView tv = (TextView) v;
                CharSequence text = tv.getText();
                if (text instanceof SpannedString) {
                    if (action == MotionEvent.ACTION_UP) {
                        int x = (int) event.getX();
                        int y = (int) event.getY();

                        x -= tv.getTotalPaddingLeft();
                        y -= tv.getTotalPaddingTop();

                        x += tv.getScrollX();
                        y += tv.getScrollY();

                        Layout layout = tv.getLayout();
                        int line = layout.getLineForVertical(y);
                        int off = layout.getOffsetForHorizontal(line, x);

                        ClickableSpan[] link = ((SpannedString)text).getSpans(off, off, ClickableSpan.class);
                        if (link.length != 0) {
                            link[0].onClick(tv);
                        } else {
                        }
                    }
                }

                return true;
            }
        });
    }

这样就可以了  下面是效果   ps:他们是一个列表,由于着急把这个记录下来还有后面的工作呢,就没录视频,这个超链也是正常可以点击的,列表后面限制的  ...也是正常的


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值