Android开发经验谈程序员Android技术知识

滑动事件冲突

2016-07-25  本文已影响327人  小菜_charry

滑动事件冲突

一般分三种:

解决方案分两种:

外部拦截

在父容器的onInterceptTouchEvent中决定是否需要拦截。
下面的父容器判断:水平方向大于竖直方向,则拦截

if (Math.abs(deltaX) > Math.abs(deltaY)) {
    intercepted = true;
} else {
    intercepted = false;
}

只需要根据需求改变判断的条件即可,完整代码:

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

    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN: {
        intercepted = false;
        if (!mScroller.isFinished()) {
            mScroller.abortAnimation();
            intercepted = true;
        }
        break;
    }
    case MotionEvent.ACTION_MOVE: {
        int deltaX = x - mLastXIntercept;
        int deltaY = y - mLastYIntercept;
        if (Math.abs(deltaX) > Math.abs(deltaY)) {
            intercepted = true;
        } else {
            intercepted = false;
        }
        break;
    }
    case MotionEvent.ACTION_UP: {
        intercepted = false;
        break;
    }
    default:
        break;
    }

    Log.d(TAG, "intercepted=" + intercepted);
    mLastX = x;
    mLastY = y;
    mLastXIntercept = x;
    mLastYIntercept = y;

    return intercepted;
}

内部拦截

内部拦截是子容器请求父容器不拦截的做法。需要配合requestDisallowInterceptTouchEvent使用。父容器也要稍微做些变动,相对来说复杂了点。

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

    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN: {
        mHorizontalScrollViewEx2.requestDisallowInterceptTouchEvent(true);
        break;
    }
    case MotionEvent.ACTION_MOVE: {
        int deltaX = x - mLastX;
        int deltaY = y - mLastY;
        Log.d(TAG, "dx:" + deltaX + " dy:" + deltaY);
        if (Math.abs(deltaX) > Math.abs(deltaY)) {
            mHorizontalScrollViewEx2.requestDisallowInterceptTouchEvent(false);
        }
        break;
    }
    case MotionEvent.ACTION_UP: {
        break;
    }
    default:
        break;
    }

    mLastX = x;
    mLastY = y;
    return super.dispatchTouchEvent(event);
}

上面例子中,若水平方向上大于垂直方向,则交由父容器来处理,其他情况都有字容器来处理。所以父容器需要变动:

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    int x = (int) event.getX();
    int y = (int) event.getY();
    int action = event.getAction();
    if (action == MotionEvent.ACTION_DOWN) {
        return false;
    } else {
        return true;
    }
}

变动:若是ACTION_DOWN则不拦截,也不能拦截。其他时候都要拦截。这样只有在子容器请求父容器不拦截的时候才交由子容器来处理点击事件。

上一篇 下一篇

猜你喜欢

热点阅读