Android 滑动冲突处理

要想解决滑动冲突就必须好好理解 Android 的事件分发机制。不了解 Android 事件分发机制的请先参考资料学习一下。

一般有 2 种方法

1 外部拦截法

这个非常简单,因为事件是从父 view 向子 view 进行分发的,所以我们可以重写父控件的 onInterceptTouchEvent, 如果父容器需要某个事件就拦截,如果不需要就不拦截交给子view处理。

伪代码如下

public boolean onInterceptTouchEvent(MotionEvent event) {
    boolean intercept = false;
    int x = (int) event.getX();
    int y = (int) event.getY();

    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            intercept = false;
            break;
        case MotionEvent.ACTION_MOVE:
            if (父容器需要这个事件) {
                intercept = true;
            } else {
                intercept = false;
            }
            break;
        case MotionEvent.ACTION_UP:
            intercept = false;
            break;
    }

    mLastX = x;
    mLastY = y;

    return intercept;
}

这里有一点需要注意,父容器不能拦截 ACTION_DOWN 事件,因为父容器一旦拦截了 ACTION_DOWN 事件那么后面所有的事件就都由它来处理了,子 view 就接收不到任何事件了。

2 内部拦截法

父容器不拦截任何事件,所有的事件都传递给子元素,如果子元素需要此事件就直接消耗掉,否则交给父容器就行处理,需要配合 requestDisallowInterceptTouchEvent 来干预父容器对事件的拦截。

伪代码如下

一要重写子view的 dispatchTouchEvent

public boolean dispatchTouchEvent(MotionEvent event) {
    int x = (int) event.getX();
    int y = (int) event.getY();

    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            parent.requestDisallowInterceptTouchEvent(true);
            break;
        case MotionEvent.ACTION_MOVE:
            int deltaX = x - mLastX;
            int deltaY = y - mLastY;
            if (父容器需要这个事件) {
                parent.requestDisallowInterceptTouchEvent(false);
            }
            break;
    }

    mLastX = x;
    mLastY = y;

    return super.dispatchTouchEvent(event); // 干预之后再扔给父容器
}

二要重写父容器的 onInterceptTouchEvent 让父容器默认拦截除 ACTION_DOWN 以外的所有事件

public boolean onInterceptTouchEvent(MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        return false;
    } else {
        return true;
    }
}

内部拦截法不太好理解,比较饶。

外部拦截法与事件分发机制流程一致,简单好理解,所以一般情况下都会优先选择外部拦截法。

 

posted @ 2016-03-15 10:38  LeslieFang  阅读(990)  评论(0编辑  收藏  举报