TextView 中确定 ClickableSpan 的具体位置

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/android_freshman/article/details/66476404

现在有一个需求是 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

猜你喜欢

转载自blog.csdn.net/android_freshman/article/details/66476404
今日推荐