android 基礎知識View (一)滑動衝突攔截和原理
阿新 • • 發佈:2019-02-04
自定義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); }