ClickableSpan в EditText до конца текстовых вызовов click() до конца строки

У меня есть 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));
        }
    }

Проблема в том, что когда я заканчиваю свой текст интервалом, а после него нет символов и нажимаю ПОСЛЕ ТОГО, он по-прежнему считается кликом для перехода, и вызывается onClick. Из-за этого я не могу поместить курсор сразу после диапазона, чтобы продолжить редактирование. Но если я печатаю любой символ, даже пробел после интервала, я могу легко поместить курсор после интервала, и все работает нормально. Есть ли способ исправить клики в тексте редактирования после кликабельного промежутка, если за ними нет символов?

1 ответ

Решение

Я нашел решение моей проблемы в ответе dor506 здесь. Но были некоторые проблемы с многострочным текстом с интервалами, поэтому я сделал несколько настроек:

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

Возможно, не самое красивое многострочное решение, но оно сработало для меня.

Другие вопросы по тегам