view的事件分发已经看过了挺多的,但是感觉自己虽然照着看了,但是还是有点了解的不是很清醒,然后这次我在想,如果在down事件时候,都是返回false的,那mFirstTouchTarget就为空了,那move事件的时候,就会直接执行这个方法,调用自己的onTouchEvent事件,那子view的就没办法调用了呀,带着这个疑惑我就又重新去翻看了一下,而且一直也只知道没有child的时候会调用自己父类的super.dispatchTouchEvent(event);
从而执行onTouchEvent方法,但是不知道此之前传递过来的viewGroup的onTouchEvent方法怎么调用到的
if (mFirstTouchTarget == null) {
// No touch targets so treat this as an ordinary view.
handled = dispatchTransformedTouchEvent(ev, canceled, null,
TouchTarget.ALL_POINTER_IDS);
}
首先,主要逻辑都是在viewGroup的dispatchTouchEvent(MotionEvent ev)
方法里面的
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (onFilterTouchEventForSecurity(ev)) {
if (actionMasked == MotionEvent.ACTION_DOWN || mFirstTouchTarget != null) {
if (!disallowIntercept) {
//因为这里都是不拦截,所以返回的是false
intercepted = onInterceptTouchEvent(ev);
}
}
//所以这里可以进入这个方法中
if (!canceled && !intercepted) {
//遍历所有event事件坐标在它之上的child
final View[] children = mChildren;
for (int i = childrenCount - 1; i >= 0; i--) {
//关键的方法,主要作用就是传递给child,调用child的dispatchTouchEvent方法,把事件传递下去
if (dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)){
//若这个方法返回的是true,则target就不为空了,当然这里考虑的是不拦截,则都是返回的false
newTouchTarget = addTouchTarget(child, idBitsToAssign);
break;
}
}
}
}
//因为这里target为空,所有执行里面的child为空的方法,相当于调用自己父类的方法super.dispatchTouchEvent(event),然后在这个方法中调用onTOuchEvent
if (mFirstTouchTarget == null) {
handled = dispatchTransformedTouchEvent(ev, canceled, null,
TouchTarget.ALL_POINTER_IDS);
}
}
private boolean dispatchTransformedTouchEvent(MotionEvent event, boolean cancel,
View child, int desiredPointerIdBits) {
final boolean handled;
if (child == null) {
handled = super.dispatchTouchEvent(event);
} else {
handled = child.dispatchTouchEvent(event);
}
return handled;
}
}
大概流程就是这样的了,若有子view可以接受到这个事件,则传递给子view,在遍历过之后执行自己的onTouchEvent方法。在传递给子view的过程,若子view没有可以接受到的了,也是target为空,执行自己的onTouchEvent方法,若为最上层的view,直接就会调用这个方法了,所以整体就是这样的逻辑。表述不是很清醒,可以理一下上面代码就知道了