【问题标题】:TextView with spans , how can I know which one is clicked on?带有 spans 的 TextView ,我怎么知道点击了哪一个?
【发布时间】:2020-02-19 16:19:15
【问题描述】:

我正在使用这个库,但是从他们拥有的 onClick 样式来看,它们都不能处理我需要的情况。 https://github.com/splitwise/TokenAutoComplete

所以我想自己做。所以我有一个ContactsCompletionView,它是一个TextView。我像这样覆盖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;

}

我的代码有效,但我的问题是,每当我在其末尾按一个 TAG 时。它得到下一个对象。我认为这是因为我只是使用:

 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 中获取文本。请问有什么办法可以解决这个问题吗?

【问题讨论】:

  • 可以在span上设置点击监听,避免所有的触摸事件解析
  • 可以在span上设置点击监听,避免所有的触摸事件解析
  • stackoverflow.com/a/13330012/2136812 解释了如何做到这一点

标签: android tags imagespan tokenautocomplete android-spannable


【解决方案1】:

您可以使用如下可点击范围:

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);

【讨论】:

  • 我接受了这个,因为这个答案适用于正常情况。由于使用带有私有/受保护类的库,有点困难,但会在下面发布我的修复
【解决方案2】:

这是我用的:

  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
}

如果 ClickStyle 设置为 NONE,则库会将光标移动到所选对象的末尾。所以我创建了一个子字符串,检查我有多少跨度,然后我用它作为我的对象的索引。为了在光标左侧显示第一个

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-08
    • 1970-01-01
    • 2016-02-08
    • 1970-01-01
    相关资源
    最近更新 更多