view的事件都返回false为何子view的onTouchEvent会被调用多次

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,直接就会调用这个方法了,所以整体就是这样的逻辑。表述不是很清醒,可以理一下上面代码就知道了

你可能感兴趣的:(安卓开发之路)