}
//5
//如果cancelChild为true 则将mFirstTouchTarget的头部去掉并回收
if (cancelChild) {
if (predecessor == null) {
mFirstTouchTarget = next;
} else {
predecessor.next = next;
}
target.recycle();
target = next;
continue;
}
predecessor = target;
target = next;
}
}
//View.java
private boolean dispatchTransformedTouchEvent(MotionEvent event, boolean cancel,
View child, int desiredPointerIdBits) {
final boolean handled;
final int oldAction = event.getAction();
//如果cancel为true进入代码块
if (cancel || oldAction == MotionEvent.ACTION_CANCEL) {
//重置event为MotionEvent.ACTION_CANCEL 触发了child的ACTION_CANCEL
event.setAction(MotionEvent.ACTION_CANCEL);
if (child == null) {
handled = super.dispatchTouchEvent(event);
} else {
handled = child.dispatchTouchEvent(event);
}
event.setAction(oldAction);
return handled;
}
…
}
复制代码
如果看过我之前发的View事件分发源码解析文章,对上面这些代码应该不陌生,没看过的推荐先去看一下再来看这一块内容。这里我重新再简略捋一遍当前场景的流程:
-
ACTION_DOWN事件过来,走入RecyclerView的onInterceptTouchEvent方法,RecyclerView没有拦截,交由ItemView处理,然后ItemView由于可以点击,所以默认消费了down事件,从而也导致了mFirstTouchTarget不为空,down事件流程结束。
-
紧接着一系列ACTION_MOVE事件过来,由于这个时候mFirstTouchTarget不为空,所以还是走进去了标注2处RecyclerView的onInterceptTouchEvent方法,这时候如果我们的滑动距离超过了最小滑动事件,那么RecyclerView内部会返回true,导致intercepted为true
-
步骤2后,紧接着会导致标注3的cancelChild也为true,进入到标注4