Android TextView Linkify拦截父视图手势

时间:2011-08-29 22:42:24

标签: android gesture linkify

问题在于,如果我链接textView,那么下载的ScrollView就不会听我设置的扫描手势。有没有办法让Linkify不会搞乱underliyng视图的手势? 我试图覆盖ontouchEvent并将false返回给ACTION_MOVE,但是scrollview的手势需要ACTION_DOWN和ACTION_UP事件才能运行。有没有办法实现这个目标?

3 个答案:

答案 0 :(得分:46)

Linkify适用于textView LinkMovementMethod的movementMethod。该运动方法认为它实现了一个垂直滚动方法,它覆盖了父对象的任何其他滚动方法。虽然可以将touchEvent分配给父级,但特定父级ScrollView需要整个序列ACTION_DOWNACTION_MOVEACTION_UP才能执行(扫描检测)。< / p>

因此我的问题的解决方案是在Linkify之后删除textView的滚动方法并处理textView的LinkMovementMethod中的onTouchEvent链接检测操作。

@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检测(仅在用户触摸链接而不是整个textview时执行)并且我没有整个LinkMovementMethod。

答案 1 :(得分:1)

@wewwire和@Ridicully答案是正确的。我刚刚创建了一个小的要点,你可以在你的项目中重复使用。

这是链接:https://gist.github.com/amilcar-andrade/e4b76840da1dc92febfc

答案 2 :(得分:0)

有一件坏事 使用autoLink标志的TextView :: setText(...)方法,

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(...)