1.首先分析ViewGroup 的dispathcTouchEvent();
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); //在这个方法里面,把 mFirstTouchTarget 置为null
resetTouchState();
}
if (actionMasked == MotionEvent.ACTION_DOWN //满足此条件进入if语句
||mFirstTouchTarget !=null) {
final boolean disallowIntercept = (mGroupFlags &FLAG_DISALLOW_INTERCEPT) !=0;
if (!disallowIntercept) {
intercepted = onInterceptTouchEvent(ev); //会执行事件拦截的方法,获取到返回值
ev.setAction(action); // restore action in case it was changed
}else {
intercepted =false;
}
}
if (!canceled && !intercepted) { //如果不拦截,就会进入这个方法
if (newTouchTarget == null && childrenCount != 0) {
for (int i = childrenCount - 1; i >= 0; i--) {//反序列的for 循环 相对布局多层view 重叠的情况
newTouchTarget = getTouchTarget(child);
if (dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)) {
//如果返回true,这个方法会为mFirstTouchTarget赋值
newTouchTarget = addTouchTarget(child, idBitsToAssign);
}
}
}
}
//如果拦截的话,上面的if语句不会执行,会往下走
if (mFirstTouchTarget ==null) {//这时mFirstTouchTarget==null,会进入这里
//这时会将child赋值为null,传入dispatchTransformedTouchEvent();
handled = dispatchTransformedTouchEvent(ev, canceled, null,TouchTarget.ALL_POINTER_IDS);
}
//这个方法 会决定是否把事件分发给子view 通过child 判断
private boolean dispatchTransformedTouchEvent(MotionEvent event, boolean cancel,View child, int desiredPointerIdBits) {
final boolean handled;
// Canceling motions is a special case. We don't need to perform any transformations
// or filtering. The important part is the action, not the contents.
final int oldAction = event.getAction();
if (cancel || oldAction == MotionEvent.ACTION_CANCEL) {
event.setAction(MotionEvent.ACTION_CANCEL);
if (child ==null) { //会调用View的dispatchTouchEvent(event)
handled =super.dispatchTouchEvent(event);
}else {//会调用child.dispatchTouchEvent(event);
handled = child.dispatchTouchEvent(event);
}
event.setAction(oldAction);
return handled;
}
到这里,ViewGroup的事件分发基本上就差不多了。接下来,分析View的事件分发过程。
2.View的dispatchTouchEvent();
ListenerInfo li = mListenerInfo; //ListenerInfo 存放了所有listener 信息 如 onClickListener()
if (li != null && li.mOnTouchListener != null
&& (mViewFlags & ENABLED_MASK) == ENABLED //是否是enabled的
&& li.mOnTouchListener.onTouch(this, event)) //如果onTounLisener() 返回false 则 result 还是false,, 否则result 为true
{
result = true;
}
if (!result && onTouchEvent(event)) {//如果 result 为false, 就会执行onTouch Event(),如果 result 为true, 就不会会执行onTouch Event()
result = true;
}
//返回 到目前还没有看到点击事件
return result;
3.View的onTouchEvent()
case MotionEvent.ACTION_UP: 里面调用了performClicke();
if (!post(mPerformClick)) {
performClick();
}
performClicke() 里面
li.mOnClickListener.onClick(this);//调用点击事件
至此,View的事件分发也清楚了。