@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
...(进行Event是否正确的判断)
boolean handled = false;
if (onFilterTouchEventForSecurity(ev)) {
final int action = ev.getAction();
final int actionMasked = action & MotionEvent.ACTION_MASK;
// Handle an initial down.
if (actionMasked == MotionEvent.ACTION_DOWN) {
// Throw away all previous state when starting a new touch gesture.
// The framework may have dropped the up or cancel event for the previous gesture
// due to an app switch, ANR, or some other state change.
cancelAndClearTouchTargets(ev);
resetTouchState();
}
...(Intercept处理及Dispatch处理)
}
if (!handled && mInputEventConsistencyVerifier != null) {
mInputEventConsistencyVerifier.onUnhandledEvent(ev, 1);
}
return handled;
}
当Action为DOWN时,这里会调用cancelAndClearTouchTargets(ev)和resetTouchState(),将清掉mFirstTouchTarget。
这里需要了解TouchTarget的具体含义,尤其是在ViewGroup里的mFirstTouchTarget,它是这个ViewGroup里的一个单链表的表头引用,用来存储其下需要事件分发的view。
因此,这里是做一组新的事件分发的准备。
/**
* Resets all touch state in preparation for a new cycle.
*/
private void resetTouchState() {
clearTouchTargets();
resetCancelNextUpFlag(this);
mGroupFlags &= ~FLAG_DISALLOW_INTERCEPT;
mNestedScrollAxes = SCROLL_AXIS_NONE;
}
/**
* Clears all touch targets.
*/
private void clearTouchTargets() {
TouchTarget target = mFirstTouchTarget;
if (target != null) {
do {
TouchTarget next = target.next;
target.recycle();
target = next;
} while (target != null);
mFirstTouchTarget = null;
}
}
之后开始判断该Action是否是需要拦截touch的事件。
我们这里的Action为DOWN,mFirstTouchTarget为空,intercepted值为false;
这里intercepted仅当事件是DOWN且需要拦截时为true(如果是鼠标点击事件,也会为true)。
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
...
if (onFilterTouchEventForSecurity(ev)) {
...(清除单链表)
// Check for interception.
final