我们接着上次文章说的Android的View分发机制。
首先我们再举一个栗子:
当一个点击事件产生之后,他的传递过程遵循如下顺序:Activity->Window->View,即事件总是先传递给Activity,Acitivity再传递给Window,最后window再传递给顶级View,顶级View接收到事件后,就会按照事件分发机制去分发事件。再考虑一种情况,如果一个View的OnTouchEvent返回false,那么它的父容器的OnTouchEvent将会被调用,依次类推。如果所有的元素都不处理这个事件,那么这个事件将会最终传递给Activity处理,即Activity的OnTouchEvent方法会被调用。
关于事件传递的机制,这里给出一些结论,根据这些结论可以更好地理解整个传递机制,如下所示:
1、同一个事件序列是指从手指接触屏幕的那一刻起,到手指离开屏幕的那一刻结束,在这个过程中所产生的一系列事件,这个事件序列以down事件开始,中间含有数不尽的move事件,最终以up事件结束。
2、正常情况下,一个事件序列只能被一个View拦截且消耗。也就是说同一个事件序列内的所有事件都只能由一个View来处理。但是通过特殊手段一个View可以将本该自己处理的事件通过onTouchEvent强行传递给其他View处理。
3、某个View一旦决定拦截,那么这一个事件序列只能由它来处理,并且它的OnInterceptTouchEvent不会再被调用。这条也很好理解,就是说当一个View决定拦截一个事件后,那么系统会把同一个事件序列内的其他方法都直接交给它来处理了,因此就不再调用这个View的OnInterceptTouchEvent去询问它是否要拦截了。
4、ViewGroup默认不拦截任何事件。
5、View没有OnInterceptTouchEvent方法,一旦事件传递给它,那么它的onTouchEvent将会被调用。
6、View的OnTouchEvent默认都会消耗事件(返回true),除非它是不可点击的(clickable和longclickable同时为false)。View的longclick属性都默认为false,clickable属性要分情况,比如Button的为true,TextView的默认是false。
7、View的enable属性不影响onTouchEvent的默认返回值。哪怕一个View是disable状态的,只要它的clickable和longclickable有一个为true,那么它的onTouchEvent就返回为true。
8、事件传递过程是由外向内的,即事件总是县传递给父元素,然后再由父元素分发给子View,通过requestDisallowInterceptTouchEvent方法可以在子元素中干预父元素的事件分发过程,但是ACTION_DOWN事件除外。