Android TextView Linkify перехватывает с помощью родительского просмотра жестов - PullRequest
8 голосов
/ 30 августа 2011

Проблема в том, что если я связываю текстовое представление, базовый ScrollView не слушает развернутые жесты, которые я установил. Есть ли способ использовать Linkify, не мешая жестам основного представления? Я попытался переопределить ontouchEvent и вернуть false в ACTION_MOVE, но для жеста просмотра прокрутки требуются события ACTION_DOWN и ACTION_UP. Есть ли способ добиться этого?

Ответы [ 3 ]

47 голосов
/ 07 сентября 2011

Linkify применяется к методу движения в textView LinkMovementMethod. Этот метод перемещения думал, что он реализует метод вертикальной прокрутки, который он перекрывает любой другой метод прокрутки, который есть у родителя. Хотя touchEvent можно передать родителю, конкретному родителю ScrollView требовалась вся последовательность ACTION_DOWN, ACTION_MOVE, ACTION_UP для выполнения (обнаружение развертки).

Таким образом, решение моей проблемы - после Linkify удалить метод прокрутки textView и обработать действие LinkMovementMethod обнаружение ссылки в onTouchEvent textView.

@override
public boolean onTouchEvent(MotionEvent event) {
        TextView widget = (TextView) this;
        Object text = widget.getText();
        if (text instanceof Spanned) {
            Spannable buffer = (Spannable) text;

            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 = widget.getLayout();
                int line = layout.getLineForVertical(y);
                int off = layout.getOffsetForHorizontal(line, x);

                ClickableSpan[] link = buffer.getSpans(off, off,
                        ClickableSpan.class);

                if (link.length != 0) {
                    if (action == MotionEvent.ACTION_UP) {
                        link[0].onClick(widget);
                    } else if (action == MotionEvent.ACTION_DOWN) {
                         Selection.setSelection(buffer,
                                 buffer.getSpanStart(link[0]),
                                 buffer.getSpanEnd(link[0]));
                    }
                    return true;
                }
            }

        }

        return false;
    }

Таким образом, у меня есть обнаружение Link_Click (выполняется только при касании пользователем ссылки, а не всего текстового просмотра), и у меня нет всего LinkMovementMethod.

2 голосов
/ 02 августа 2015

@ weakwire и @Ridicully ответы верны. Я только что создал небольшую сущность, которую вы можете повторно использовать в своем проекте.

Это ссылка: https://gist.github.com/amilcar-andrade/e4b76840da1dc92febfc

0 голосов
/ 25 ноября 2015

Есть небольшая неприятность в том, что метод TextView :: setText (...), использующий флаг autoLink,

if (mAutoLinkMask != 0) {
        Spannable s2;

        if (type == BufferType.EDITABLE || text instanceof Spannable) {
            s2 = (Spannable) text;
        } else {
            s2 = mSpannableFactory.newSpannable(text);
        }

        if (Linkify.addLinks(s2, mAutoLinkMask)) {
            text = s2;
            type = (type == BufferType.EDITABLE) ? BufferType.EDITABLE : BufferType.SPANNABLE;

            /*
             * We must go ahead and set the text before changing the
             * movement method, because setMovementMethod() may call
             * setText() again to try to upgrade the buffer type.
             */
            mText = text;

            // Do not change the movement method for text that support text selection as it
            // would prevent an arbitrary cursor displacement.
            if (mLinksClickable && !textCanBeSelected()) {
                setMovementMethod(LinkMovementMethod.getInstance());
            }
        }
    }

Поэтому я потратил некоторое время, чтобы понять, почему я отключаю ссылки в ListView элемент, но иногда он получает ссылку!

Вам необходимо установить этот флаг в нужное значение, а затем вызвать setText (...)

...