版权声明:本文为博主原创文章,转载请注明出处。 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