[英]How to get x,y position of clicked span in android TextView?
I have a spannable Textview.我有一个可跨越的 Textview。 I want to show popup window on top of selected span inside TextView
.我想在TextView
内的选定跨度顶部显示弹出窗口。 like this:像这样:
my code is:我的代码是:
String definition = textView.getText().toString().trim();
textView.setMovementMethod(LinkMovementMethod.getInstance());
textView.setText(definition, TextView.BufferType.SPANNABLE);
Spannable spans = (Spannable) textView.getText();
Integer[] indices = getIndices(
textView.getText().toString(), ' ');
int start = 0;
int end = 0;
for (int i = 0; i <= indices.length; i++) {
ClickableSpan clickSpan = getClickableSpan();
end = (i < indices.length ? indices[i] : spans.length());
spans.setSpan(clickSpan, start, end,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
start = end + 1;
}
private Integer[] getIndices(String s, char c) {
int pos = s.indexOf(c, 0);
List<Integer> indices = new ArrayList<Integer>();
while (pos != -1) {
indices.add(pos);
pos = s.indexOf(c, pos + 1);
}
return (Integer[]) indices.toArray(new Integer[0]);
}
private ClickableSpan getClickableSpan() {
return new ClickableSpan() {
@SuppressLint("ClickableViewAccessibility")
@Override
public void onClick(View widget) {
TextView tv = (TextView) widget;
final String word = tv
.getText()
.subSequence(tv.getSelectionStart(),
tv.getSelectionEnd()).toString();
tv.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
popup(word, (int) event.getRawX(), (int) event.getRawY());
return false;
}
});
}
};
}
as you see in image code working but because of onTouch
called before onClick
in android, popup showing word that clicked in prior step.正如您在图像代码中看到的那样,但由于在 android 中的onClick
之前调用了onTouch
,弹出窗口显示了在上一步中单击的单词。 sorry for may bad English.抱歉可能英语不好。
val parentTextViewRect = Rect()
val textViewLayout = parentTextView.layout
val startXCoordinatesOfClickedText = textViewLayout.getPrimaryHorizontal(spanStart).toDouble()
val endXCoordinatesOfClickedText = textViewLayout.getPrimaryHorizontal(spanEnd).toDouble()
val currentLineStartOffset = textViewLayout.getLineForOffset(spanStart)
val currentLineEndOffset = textViewLayout.getLineForOffset(spanEnd)
// 文本是否跨行
val keywordIsInMultiLine = currentLineStartOffset != currentLineEndOffset
textViewLayout.getLineBounds(currentLineStartOffset, parentTextViewRect)
// 屏幕中的真实位置
val parentTopAndBottomOffset = parentTextView.top + parentTextView.paddingTop
parentTextViewRect.top += parentTopAndBottomOffset
parentTextViewRect.bottom += parentTopAndBottomOffset
val parentLeftOffset = parentTextView.left + parentTextView.paddingLeft
parentTextViewRect.left += (parentLeftOffset + startXCoordinatesOfClickedText).toInt()
parentTextViewRect.right = (parentTextViewRect.left + endXCoordinatesOfClickedText - startXCoordinatesOfClickedText).toInt()
var spanTextLeft = if (keywordIsInMultiLine) {
parentTextViewRect.left
} else {
(parentTextViewRect.left + parentTextViewRect.right) / 2
}
val spanTextTop = parentTextViewRect.top
Log.d("MainActivity", "spanTextLeft = $spanTextLeft")
Log.d("MainActivity", "spanTextTop = $spanTextTop")
To get x
and y
you can set OnTouchListener
to register click event要获得x
和y
您可以设置OnTouchListener
来注册点击事件
private void setOnTouchListener() {
textView.setOnTouchListener((view, event) -> {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
float clickedX = event.getX();
float clickedY = event.getY();
}
return false;
});
}
private fun setOnTouchListener() {
text_view.setOnTouchListener { view, event ->
if (event?.action == MotionEvent.ACTION_DOWN) {
val clickedX = event.x
val clickedY = event.y
}
false
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.