//判断一系列条件看是否需要进行拦截,canChildScrollUp为判断列表是否可以向上滚动(手势从上往下滑)
//mRefreshing处于刷新状态也不会拦截,mNestedScrollInProgress为嵌套滑动机制
if (!isEnabled() || mReturningToStart || canChildScrollUp()
|| mRefreshing || mNestedScrollInProgress) {
// Fail fast if we're not in a state where a swipe is possible
return false;
}
图
graph TD;
A(Start) -->|Touch事件进行分发| B[onInterceptTouchEvent];
B -->|根据条件1判断不直接return false时执行下面流程|C[根据Event的Action类型处理]
C -->|ACTION_DOWN| D[记录按下的Y值且设置mIsBeingDragged=false]
C -->|ACTION_MOVE|E[达到阈值是mIsBeingDragged=true]
C -->|ACTION_UP|F[恢复mIsBeingDragged值为false]
D-->G[return mIsBeingDragged确定是否拦截]
E-->G
F-->G
G-->|mIsBeingDragged=false时进入|H[onTouchEvent]
H -->|根据条件1判断需要消费该事件时继续执行下面流程|I[根据Event的Action类型处理]
I -->|ACTION_DOWN| J[获取此时的mActivePointerId重置mIsBeingDragged为false]
I-->|ACTION_MOVE|K[根据down中获取的mActivityPointerId获取y值来处理刷新View的移动操作]
I -->|ACTION_UP|L[根据滑动的值来判断是否触发刷新操作]
public boolean onInterceptTouchEvent(MotionEvent ev) {
ensureTarget();
final int action = ev.getActionMasked();
int pointerIndex;
//如果正在执行返回到开始位置的动画且触摸为按下时,置为false进行中断操作
if (mReturningToStart && action == MotionEvent.ACTION_DOWN) {
mReturningToStart = false;
}
//判断一系列条件看是否需要进行拦截,canChildScrollUp为判断列表是否可以向上滚动(手势从上往下滑)
//mRefreshing处于刷新状态也不会拦截,mNestedScrollInProgress为嵌套滑动机制
if (!isEnabled() || mReturningToStart || canChildScrollUp()
|| mRefreshing || mNestedScrollInProgress) {
// Fail fast if we're not in a state where a swipe is possible
return false;
}
switch (action) {
case MotionEvent.ACTION_DOWN:
setTargetOffsetTopAndBottom(mOriginalOffsetTop - mCircleView.getTop());
mActivePointerId = ev.getPointerId(0);
mIsBeingDragged = false;
pointerIndex = ev.findPointerIndex(mActivePointerId);
if (pointerIndex < 0) {
return false;
}
//获取刚按下的y值
mInitialDownY = ev.getY(pointerIndex);
break;
case MotionEvent.ACTION_MOVE:
if (mActivePointerId == INVALID_POINTER) {
Log.e(LOG_TAG, "Got ACTION_MOVE event but don't have an active pointer id.");
return false;
}
pointerIndex = ev.findPointerIndex(mActivePointerId);
if (pointerIndex < 0) {
return false;
}
//startDragging中判断是否达到拖拽的阈值
final float y = ev.getY(pointerIndex);
startDragging(y);
break;
case MotionEvent.ACTION_POINTER_UP:
onSecondaryPointerUp(ev);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mIsBeingDragged = false;
mActivePointerId = INVALID_POINTER;
break;
}
return mIsBeingDragged;
}
public boolean onTouchEvent(MotionEvent ev) {
final int action = ev.getActionMasked();
int pointerIndex = -1;
if (mReturningToStart && action == MotionEvent.ACTION_DOWN) {
mReturningToStart = false;
}
if (!isEnabled() || mReturningToStart || canChildScrollUp()
|| mRefreshing || mNestedScrollInProgress) {
// Fail fast if we're not in a state where a swipe is possible
return false;
}
switch (action) {
case MotionEvent.ACTION_DOWN:
mActivePointerId = ev.getPointerId(0);
mIsBeingDragged = false;
break;
case MotionEvent.ACTION_MOVE: {
pointerIndex = ev.findPointerIndex(mActivePointerId);
if (pointerIndex < 0) {
Log.e(LOG_TAG, "Got ACTION_MOVE event but have an invalid active pointer id.");
return false;
}
final float y = ev.getY(pointerIndex);
startDragging(y);
if (mIsBeingDragged) {
final float overscrollTop = (y - mInitialMotionY) * DRAG_RATE;
if (overscrollTop > 0) {
moveSpinner(overscrollTop);
} else {
return false;
}
}
break;
}
case MotionEvent.ACTION_POINTER_DOWN: {
pointerIndex = ev.getActionIndex();
if (pointerIndex < 0) {
Log.e(LOG_TAG,
"Got ACTION_POINTER_DOWN event but have an invalid action index.");
return false;
}
mActivePointerId = ev.getPointerId(pointerIndex);
break;
}
case MotionEvent.ACTION_POINTER_UP:
onSecondaryPointerUp(ev);
break;
case MotionEvent.ACTION_UP: {
pointerIndex = ev.findPointerIndex(mActivePointerId);
if (pointerIndex < 0) {
Log.e(LOG_TAG, "Got ACTION_UP event but don't have an active pointer id.");
return false;
}
if (mIsBeingDragged) {
final float y = ev.getY(pointerIndex);
final float overscrollTop = (y - mInitialMotionY) * DRAG_RATE;
mIsBeingDragged = false;
finishSpinner(overscrollTop);
}
mActivePointerId = INVALID_POINTER;
return false;
}
case MotionEvent.ACTION_CANCEL:
return false;
}
return true;
}