事件分发主要分为2部分,View分发与ViewGroup,在了解事件分发的之前首先了解一下View与ViewGroup,View是没有子控件的,如Button,TextView等,但是ViewGroup是有子控件的,如ViewPager,RelativeLayout。
首先看看View的事件分发,主要是两个方法dispatchTouchEvent和OnTouchEvent,从流程是从Activity-View,Activity的dispatchTouchEvent是事件分发的第一入口。
我们继承一个Button重写他的dispatchTouchEvent和OnTouchEvent

调用button的setOnTouchListener和setOnClickListener

重写activity的dispatchTouchEvent和OnTouchEvent

点击button,我们会看到下面这个Log打印顺序

在这里你可能会奇怪为什么Activity的OnTouchEvent为什么没有调用,这是因为我们的Button在OnTouchEvent中已经处理了事件,最后执行的click,当我们将Button的OnTouchEvent返回值改为false,我们会看到下面的这中情况。
这时候Activity的OnTouchEvent就被调用了,因为我们在button的OnTouchEvent不处理事件,这样最后没人处理我们只能将事件返回给Activity,这样Activity的OnTouchEvent就会被调用

这里我们看到最后没有执行click事件,并且UP也没有执行了,这是因为button在Down后没有处理事件,最后到了activity那里处理

如果我们在up的时候不处理,返回一个false

这样我们的Down和Up都执行但是最后的click没有执行,因为button没有处理事件,所以事件最后就到了Activity哪里,执行了OnTouchEvent

最后看书:



下面来说说ViewGroup的分发事件,其实原理跟View差不多,只不过它多了一个onInterceptTouchEvent这个方法是用来控制事件是给自己消费还是分发给子控件。
1.默认的onInterceptTouchEvent总是返回false的,就是不拦截touch事件,直接分发给了子控件。所以假如我们自定义了组合控件,譬如image+文字的组合控件,并且在activity里面注册监听期待点击它的时候会产生响应,那么我们就需要重写onInterceptTouchEvent了让它返回true,将事件拦截下来。
2.如果触摸的时候,我们只想出发ontouch监听,想屏蔽onclick监听的话,就需要在ontouch里面返回true就可以了
3.android事件分发是先传递到viewgroup,然后才传递到view的
4.子view如果将传递的事件消费处理掉,viewgroup当中是接收不到任何事件的
5.简单来讲,dispatchTouchEvent方法是为了onTouch监听的,onTouchEvent是为了onClick监听的。如果ontouch监听返回false,事件会传递到onTouchEvent当中触发onClick,如果是true的话就不会继续往下传递了。