这里的大致意思是,假设设置了mCloseOnTouchOutside属性为true(相应xml中的android:windowCloseOnTouchOutside属性),且当前事件为down事件。且down事件发生在该Activity范围之外,而且DecorView不为null,就返回true。非常明显。dialog形的Activity可能会发生这种情况。
以下须要重点来看下ViewGroup中的dispatchTouchEvent方法了:
public boolean dispatchTouchEvent(MotionEvent ev) {
//调试用的
if (mInputEventConsistencyVerifier != null) {
mInputEventConsistencyVerifier.onTouchEvent(ev, 1);
}
//handled为返回值,表示是否有view消费了该事件。
boolean handled = false;
//是否要过滤掉该Touch事件。大致是这个意思
if (onFilterTouchEventForSecurity(ev)) {
final int action = ev.getAction();
final int actionMasked = action & MotionEvent.ACTION_MASK;
if (actionMasked == MotionEvent.ACTION_DOWN) {
//因为down事件代表一个系列事件的开始,因此假设是down事件,
//1、就清空掉曾经消费事件的目标view,这里主要指清空掉mFirstTouchTarget链表(保存接受Touch事件的单链表,这点在后面的代码中会看到)。并将mFirstTouchTarget置为null。
//2、重置触摸状态,重置了disallowIntercept相应的标志位。该变量的值决定了onInterceptTouchEvent方法是否有效,这点后面我们会看到;还有就是重置来View的mPrivateFlags标志位,这个没去了解详细是干嘛用的。
一般在发生app的切换。或者ANR等情况时。代码会走到这里,这一点源代码的凝视里也有。
cancelAndClearTouchTargets(ev);
resetTouchState();
}
// 标记是否要拦截该Touch事件,true表示拦截。false表示不拦截
final boolean intercepted;
//假设当前事件为down事件。或者可接受Touch事件的链表不为空。就运行if语句里的逻辑。这里注意,
//1、因为down事件是一个完整事件序列的的起点,因此当发生down事件时。逻辑走到这里。还没有找到消费down事件的view,因此mFirstTouchTarget为null,
//2、而对后面的move和up事件,假设前面的down事件被某个view消费掉了,则mFirstTouchTarget不为null。
上面两种情况都会使代码进入if分支中来。
if (actionMasked == MotionEvent.ACTION_DOWN
|| mFirstTouchTarget != null) {
//是否不同意拦截。默觉得false,也就是同意该方法能够通过 requestDisallowInterceptTouchEvent方法来设置
final boolean disallowIntercept = (mGroupFlags & FLAG_DISALLOW_INTERCEPT) != 0;
// 假设同意拦截,则onInterceptTouchEvent有效,依据我们覆写的该方法的返回值来推断是否拦截,否则。onInterceptTouchEvent无效,不正确该事件进行拦截。
if (!disallowIntercept) {
intercepted = onInterceptTouchEvent(ev);
ev.setAction(action); // restore action in case it was changed
} else {
intercepted = false;
}
} else {
// 假设当前事件不是down事件。且之前在分发down事件的时候没有找到消费down事件的目标view,也即mFirstTouchTarget为null,则直接拦截该事件。
intercepted = true;
}
// 检查当前事件是否被取消
final boolean canceled = resetCancelNextUpFlag(this)
|| actionMasked == MotionEvent.ACTION_CANCEL;
// Update list of touch targets for pointer down, if needed.
final boolean split = (mGroupFlags & FLAG_SPLIT_MOTION_EVENTS) != 0;
//保存消费事件的目标View所相应的 TouchTarget对象
TouchTarget newTouchTarget = null;
//事件是否已经分发到了目标View中。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/shouji/article-84984-6.html
好自为之