Android 带跨距的文本视图,如何知道单击了哪一个?
我正在使用这个库,但是从它们拥有的onClick样式来看,它们都不能处理我需要的情况。 所以我想做我自己的。所以我有一个Android 带跨距的文本视图,如何知道单击了哪一个?,android,tags,imagespan,tokenautocomplete,android-spannable,Android,Tags,Imagespan,Tokenautocomplete,Android Spannable,我正在使用这个库,但是从它们拥有的onClick样式来看,它们都不能处理我需要的情况。 所以我想做我自己的。所以我有一个联系人完成视图,它是一个文本视图。我覆盖了onTouchEvent,如下所示: override fun onTouchEvent(event: MotionEvent): Boolean { val action = event.actionMasked val text = text var handled = super.onTouchEvent
联系人完成视图
,它是一个文本视图
。我覆盖了onTouchEvent,如下所示:
override fun onTouchEvent(event: MotionEvent): Boolean {
val action = event.actionMasked
val text = text
var handled = super.onTouchEvent(event)
if (isFocused && text != null && action == MotionEvent.ACTION_UP) {
val offset = getOffsetForPosition(event.x, event.y)
if (offset != -1) {
var offseted = text.substring(offset, text.length)
var indexLeft = offseted.indexOf("(") + 1
var indexRight = offseted.indexOf(")")
if (indexLeft > 0 && indexRight > indexLeft)
Toast.makeText(context, offseted.substring(indexLeft, indexRight), Toast.LENGTH_SHORT).show()
}
}
return handled
}
这就是他们所拥有的,但我不能使用TokenImageSpan
,因为它是一个受保护的类:
@Override
public boolean onTouchEvent(@NonNull MotionEvent event) {
int action = event.getActionMasked();
Editable text = getText();
boolean handled = false;
if (tokenClickStyle == TokenClickStyle.None) {
handled = super.onTouchEvent(event);
}
if (isFocused() && text != null && lastLayout != null && action == MotionEvent.ACTION_UP) {
int offset = getOffsetForPosition(event.getX(), event.getY());
if (offset != -1) {
TokenImageSpan[] links = text.getSpans(offset, offset, TokenImageSpan.class);
if (links.length > 0) {
links[0].onClick();
handled = true;
} else {
//We didn't click on a token, so if any are selected, we should clear that
clearSelections();
}
}
}
if (!handled && tokenClickStyle != TokenClickStyle.None) {
handled = super.onTouchEvent(event);
}
return handled;
}
我的代码是有效的,但我的问题是每当我在代码末尾按下标记时。它获取下一个对象。我假设这是因为我只使用:
val offset = getOffsetForPosition(event.x, event.y)
if (offset != -1) {
var offseted = text.substring(offset, text.length)
}
使用时:
if (offset != -1) {
TokenImageSpan[] links = text.getSpans(offset, offset, TokenImageSpan.class);
}
TokenImageSpan
扩展了ImageSpan
,因此我可以这样使用它,但我不知道如何从ImageSpan
获取文本。有什么办法可以解决这个问题吗?您可以使用可点击的范围,如下所示:
SpannableString ss = new SpannableString("your string comes
here");
ClickableSpan clickableSpan = new ClickableSpan() {
@Override
public void onClick(View textView) {
//do your stuff here on click
}
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
}
};
//set click range
ss.setSpan(clickableSpan, 8, 15,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//your text view or edittext
textView.setText(ss);
textView.setMovementMethod(LinkMovementMethod.getInstance());
textView.setHighlightColor(Color.TRANSPARENT);
这就是我使用的:
override fun onTouchEvent(event: MotionEvent): Boolean {
val action = event.actionMasked
val text = text
var handled = super.onTouchEvent(event)
var offset = getOffsetForPosition(event.getX(), event.getY())
if (isFocused && text != null && action == MotionEvent.ACTION_UP) {
var cursor = this@ContactsCompletionView.selectionEnd
if (cursor < 0)
cursor = 0
val links: Array<ViewSpan> = text.getSpans(0, cursor, ViewSpan::class.java)
if (objects.size > 0 && objects.size >= links.size && links.size > 0 && offset < cursor)
Snackbar().make(this, objects[links.size - 1].address, com.google.android.material.snackbar.Snackbar.LENGTH_SHORT).show()
}
return handled
}
覆盖事件(事件:MotionEvent):布尔值{
val action=event.actionMasked
val text=文本
var handled=super.onTouchEvent(事件)
var offset=getOffsetForPosition(event.getX(),event.getY())
if(isFocused&&text!=null&&action==MotionEvent.action\u UP){
变量游标=this@ContactsCompletionView.selectionEnd
如果(光标<0)
光标=0
val links:Array=text.getspan(0,游标,ViewSpan::class.java)
如果(objects.size>0&&objects.size>=links.size&&links.size>0&&offset
如果ClickStyle设置为“无”,则库将在所选对象的末尾移动光标。所以我创建了一个子串,检查我有多少跨距,然后用它作为我的对象的索引。为了显示光标左侧的第一个按钮您可以在跨度上设置一个点击监听器,并避免所有的触摸事件分析您可以在跨度上设置一个点击监听器,并避免所有的触摸事件分析解释了如何做到这一点,我接受了这一点,因为这个答案适用于正常情况。由于使用带有私有/受保护类的库,这有点困难,但将在下面发布我的修复