本文粗略解析下事件分发机制,后续会分析下源码,但愿可以帮助到你们解惑一二。函数
从一个例子提及cdn
在实践中,大多数须要了解事件分发机制的可能就是滑动冲突了,须要了解何时到底谁应该处理这个事件,先来看个例子,当咱们点击区域Viewblog
假如ViewGroup和View都默认不处理事件,不复写对应函数事件
因为onTouchEvent中返回了false,同时也就表明着不关心本次事件(我不关心此次手势,不要来找我了),后续的MOVE,UP事件也不会传递进来源码
假设View是须要处理事件,好比是Button之类的View,默认是可点击的it
注意上述的前提是ViewGroup不会对此事件进行拦截,由于在DOWN事件传递到View的ontouchEvent以前,ViewGroup是有一次拦截机会的,若是ViewGroup的onInterceptTouchEvent返回false,则不拦截,可是注意下一次的MOVE、UP等事件仍是会走ViewGroup拦截的判断,可根据逻辑进行拦截处理,若是没有拦截,可是View的ontouchEvent返回了false,也就表示下面没有View是愿意处理这个事件的,那么这个烫手的山芋(事件)仍是会回到ViewGroup的ontouchEvent中io
同时可见DOWN事件的返回值,其实就是表示着View自己对本次事件处理的意愿如何,True则表明着愿意处理该事件,false则表明不关心本次事件class
假如ViewGroup在DOWN事件中,拦截了事件onInterceptTouchEvent返回了true,那么此时事件直接转到ViewGroup的ontouchEvent中,后续的MOVE、UP事件也会交给ViewGroup处理,View是没有机会处理到事件的,即便此时调用requestDisallowInterceptTouchEvent也是无效的request
假如ViewGroup在DOWN事件中没有拦截事件,可是在MOVE中却对事件进行了拦截处理,好比相似如ScrollView同样,是能够对其中的View进行点击处理的,可是在滑动时,ScrollView须要处理本身的逻辑,这时候就在MOVE中拦截了事件lazyload
同一时间序列事件是指以down事件开始,中间含有数量不定的move事件,最终以up事件结束。
各个View的onTouchEvent方法对DOWN事件的处理,表明了该View对以此DOWN开始的整个手势事件的处理意愿,True表明须要处理这次事件,false则表示不关心,事件会回传到上层View的ontouchEvent中
若是ViewGroup一旦决定拦截一个事件,也就是onInterceptTouchEvent返回True,那么后续的同一时间序列事件将会被默认拦截,不会再调用onInterceptTouchEvent方法,后续事件会交给ontouchEvent进行处理
事件一旦交给一个View处理,那么它就必须消耗掉,不然同一事件序列中剩下的事件就再也不交给他来处理了,若是ontouchEvent中返回false,那么后续事件不会再传递进来
若是ViewGroup拦截了一个半路的事件(好比,MOVE),这个事件将会被系统变成一个CANCEL事件,并传递给以前处理该手势(gesture)的子View,并且不会再传递(不管是被拦截的MOVE仍是系统生成的CANCEL)给ViewGroup的onTouchEvent方法。只有再到来的事件才会传递到ViewGroup的onTouchEvent方法中。