1. 程式人生 > >android 基礎知識View (一)滑動衝突攔截和原理

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);
}