TextView 中确定 ClickableSpan 的具体位置

现在有一个需求是 TextView 中要有特殊的字符加颜色还需要可以点击弹出pop,点击跳转和改变颜色 这个需求 ClickableSpan 就可以胜任。但是找到具体位置就有点困难。

这里写图片描述


1.确定 ClickableSpan 的具体位置

注意 需要 加上 textView.setMovementMethod(LinkMovementMethod.getInstance());表示可以点击的

SpannableString ssb = new SpannableString("xxxxx");
ssb.setSpan(new ClickableSpan() {
                    @Override
                    public void onClick(View widget) {
                        TextView parentTextView = (TextView) widget;
                        Rect parentTextViewRect = new Rect();

                        // Initialize values for the computing of clickedText position
                        SpannableString completeText = (SpannableString)(parentTextView).getText();
                        Layout textViewLayout = parentTextView.getLayout();

                        double startOffsetOfClickedText = completeText.getSpanStart(this);
                        double endOffsetOfClickedText = completeText.getSpanEnd(this);

                        double startXCoordinatesOfClickedText = textViewLayout.getPrimaryHorizontal((int)startOffsetOfClickedText);
                        double endXCoordinatesOfClickedText = textViewLayout.getPrimaryHorizontal((int)endOffsetOfClickedText);

                        // Get the rectangle of the clicked text
                        int currentLineStartOffset = textViewLayout.getLineForOffset((int)startOffsetOfClickedText);
                        int currentLineEndOffset = textViewLayout.getLineForOffset((int)endOffsetOfClickedText);

                        boolean keywordIsInMultiLine = currentLineStartOffset != currentLineEndOffset;
                        textViewLayout.getLineBounds(currentLineStartOffset, parentTextViewRect);

                        // Update the rectangle position to his real position on screen
                        int[] parentTextViewLocation = {0,0};
                        parentTextView.getLocationOnScreen(parentTextViewLocation);

                        double parentTextViewTopAndBottomOffset = (
                                parentTextViewLocation[1] -
                                        parentTextView.getScrollY() +
                                        parentTextView.getCompoundPaddingTop()
                        );

                        parentTextViewRect.top += parentTextViewTopAndBottomOffset;
                        parentTextViewRect.bottom += parentTextViewTopAndBottomOffset;

                        parentTextViewRect.left += (
                                parentTextViewLocation[0] +
                                        startXCoordinatesOfClickedText +
                                        parentTextView.getCompoundPaddingLeft() -
                                        parentTextView.getScrollX()
                        );
                        parentTextViewRect.right = (int) (
                                parentTextViewRect.left +
                                        endXCoordinatesOfClickedText -
                                        startXCoordinatesOfClickedText
                        );

                        int x = (parentTextViewRect.left + parentTextViewRect.right) / 2;
                        int y = parentTextViewRect.bottom;
                        if (keywordIsInMultiLine) {
                            x = parentTextViewRect.left;
                        }

                        spanTextLeft = x;
                        spanTextTop = parentTextViewRect.top;
                        spanTextBottom = y;

                        ///显示弹出层
                        showSubTitlePop(widget,name,stockid.toUpperCase());

                    }

                    @Override
                    public void updateDrawState(TextPaint ds) {
                        super.updateDrawState(ds);
                           ds.setColor(xxxx); // 设置文本颜色
                           // 去掉下划线
                          ds.setUnderlineText(false);
                    }
                }, start, start + name.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

注意点:

1.double startOffsetOfClickedText = completeText.getSpanStart(this);
这个this是 ClickableSpan onclick 里面的this,其他的 this 是获取不到具体的值得。
2. x,y 就是最终 左边距和上边距,获取的是全屏的具体距离不是相对 textView 的


2.参考资料

How get coordinate of a ClickableSpan inside a TextView?

http://stackoverflow.com/questions/11905486/how-get-coordinate-of-a-clickablespan-inside-a-textview

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值