Java ClickableSpan在EditText中指向文本末尾调用click()指向行尾

Java ClickableSpan在EditText中指向文本末尾调用click()指向行尾,java,android,android-edittext,clickablespan,Java,Android,Android Edittext,Clickablespan,我有一个EditText和TextWatcher,在其中我检查模式以确定在何处创建ClickableSpans private void checkSpans(){ Matcher matcher = Pattern.compile("(^|[ \\t\\n])#\\w+").matcher(text); while (matcher.find()) { BlueClickableSpan[] spans = getText().getSpans(matcher.

我有一个EditText和TextWatcher,在其中我检查模式以确定在何处创建ClickableSpans

private void checkSpans(){
    Matcher matcher = Pattern.compile("(^|[ \\t\\n])#\\w+").matcher(text);
    while (matcher.find()) {
        BlueClickableSpan[] spans = getText().getSpans(matcher.start(), matcher.end(), BlueClickableSpan.class);
        for (BlueClickableSpan span : spans) {
            text.removeSpan(span);
        }
        text.setSpan(new BlueClickableSpan(),
                matcher.start(),
                matcher.end(),
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
}
这是我的定制Span类

private class BlueClickableSpan extends ClickableSpan {

        @Override
        public void onClick(View view) {
            Spanned s = getText();
            int start = s.getSpanStart(this);
            int end = s.getSpanEnd(this);
            String clickedString = s.subSequence(start, end).toString().trim();
            if (onSpanClick != null)
                onSpanClick.onClick(clickedString);
        }

        @Override
        public void updateDrawState(TextPaint ds) {
            ds.setColor(ContextCompat.getColor(IdeaFlowApp.getAppContext(), R.color.main_blue));
        }
    }

问题是,当我用一个span结束我的文本时,它后面没有字符,我在它后面点击,它仍然算作点击span,并调用onClick。正因为如此,我无法将光标放在跨度的正后方继续编辑。但是,如果我打印任何符号,即使是空格在跨度之后,我可以很容易地将光标放在跨度之后,一切正常。如果在可点击范围之后没有符号,有没有办法修复edittext中的点击?

我在回答中找到了解决问题的方法。 但是带跨距的多行文本存在一些问题,所以我做了一些调整:

public class MovementMethod extends LinkMovementMethod {

    @Override
    public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
        int action = event.getAction();

        if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) {
            int x = (int) event.getX();
            int y = (int) event.getY();

            x -= widget.getTotalPaddingLeft();
            y -= widget.getTotalPaddingTop();

            x += widget.getScrollX();
            y += widget.getScrollY();

            Layout layout = getLayout();
            int line = layout.getLineForVertical(y);
            int off = layout.getOffsetForHorizontal(line, x);

            int lineLength = line;
            String[] lines = getText().toString().split("\n");
            for (int i = 0; i <= line; i++) {
                lineLength += lines[i].length();
            }

            if (off >= lineLength) {
               // Return true so click won't be triggered in the leftover empty space
                return true;
            }
        }

        return super.onTouchEvent(widget, buffer, event);
    }
}
public类MovementMethod扩展了LinkMovementMethod{
@凌驾
公共布尔onTouchEvent(TextView小部件、可扩展缓冲区、MotionEvent事件){
int action=event.getAction();
if(action==MotionEvent.action|u UP | action==MotionEvent.action|u DOWN){
int x=(int)event.getX();
int y=(int)event.getY();
x-=widget.getTotalAddingleft();
y-=widget.getTotalAddingTop();
x+=widget.getScrollX();
y+=widget.getScrollY();
Layout=getLayout();
int line=layout.getLineForVertical(y);
int off=layout.getOffsetForHorizontal(直线,x);
int lineLength=直线;
字符串[]行=getText().toString().split(“\n”);
对于(int i=0;i=lineLength){
//返回true,这样就不会在剩余的空白处触发单击
返回true;
}
}
返回super.onTouchEvent(小部件、缓冲区、事件);
}
}

也许不是最漂亮的多行解决方案,但它对我很有效。

我也有类似的问题,它对我很有帮助。可能是重复的