android 基础知识View (一)滑动冲突拦截和原理

自定义View滑动冲突现象:  第一种是同向,第二种为异向,第三种为前两种的组合模式

滑动冲突解决方案:

首先决定x和y移动方向的长度来决定是x还是y的移动

第一外部拦截法:

    @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;  //首先点击事件不拦截因为一旦拦截了之后全部的事件都会交给父View处理,那就没有处理滑动的必要了
//            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)) {  //根据x和y移动的绝对值做一次判断  只消耗水平方向时间
                intercepted = true;
            } else {
                intercepted = false;
            }
            break;
        }
        case MotionEvent.ACTION_UP: {  //这里只是说为了满足子View 去处理click时间,
            // 要知道一旦父view处理了,那后续的事件都交给他处理。比如消耗了move ,
            // 那 up也是他处理(不顾onintercepted 是否为空), up是最后一个事件
            intercepted = false;
            break;
        }
        default:
            break;
        }

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

        return intercepted;
    }
】

第二种内部拦截法:

就是处理第二种方式:

父view的表现:

@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) {  //父view必然是不拦截的,因为事件流一旦拦截,之后都交给他处理了
        mLastX = x;
        mLastY = y;
        if (!mScroller.isFinished()) {
            mScroller.abortAnimation();
            return true;
        }
        return false;
    } else {   //其他的事件流都表现为拦截的处理。
        return true;
    }
}

子view的表现:

@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);  //告诉父View不去拦截
        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);//告诉父View去拦截
        }
        break;
    }
    case MotionEvent.ACTION_UP: {
        break;
    }
    default:
        break;
    }

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

猜你喜欢

转载自blog.csdn.net/sheng2459704496/article/details/81740922