Android事件分发流程详解

View的事件分发流程主要区分2种情况
一种是直接继承View的控件
一种是继承ViewGroup的控件
任何一个View不管是直接继承于View的单个控件,还是ViewGroup的布局都会首先调用dispatchTouchEvent方法,当Viewgroup中有子view时将由Viewgroup的dispatchTouchEvent方法去决定是否拦截事件,拦截条件为是判断 是否允许拦截的标志值是否为0和onInterceptTouchEvent方法的返回值是否为true,这2个条件满足任何一个该ViewGroup下的子view将获取不到事件,允许拦截事件的标志值默认是非0,所以一般通过onInterceptTouchEvent方法来拦截事件处理。如果不重写ViewGroup的onInterceptTouchEvent方法该值默认为false,所以将由viewgroup进行子view的遍历调用子view的dispatchTouchEvent方法如果任何一个子view的dispatchTouchEvent方法返回true则事件被该子view消费,不在传递。
在以下几种情况下会将该事件交给viewgoup进行消费不在传递:
1、viewgroup拦截事件的情况下。
2、没有子view消费该事件的情况(或者点击viewgroup的空白区域)。
这些情况将调用dispatchTouchEvent方法,该方法内部先调用View的onTouch事件如果onTouch事件返回true将不在调用onClick事件也就是不会再调用onTouchEvent方法。对于一个view如果该view(Imageview)是默认不可点击的即unclickable时如果一个事件返回的是false则不会再触发往后的事件,例如ACTION_DOWN返回false时后面的ACTION_MOVE和ACTION_UP将不在触发,只有前一个事件返回true时才会触发下一个事件。对于可点击控件如Button则不管ontouch返回是false也仍然会接收到下一个事件。
下面对事件的分发及处理在Activity、ViewGroup、View之间的关系进行了总结
1、假设都是返回默认值的情况下,事件分发的顺序是从上往下:Activity的dispatchTouchEvent()—>ViewGroup的dispatchTouchEvent()—>View的dispatchTouchEvent()
2、假设都是返回默认值的情况下,事件处理的顺序是从下往上:View的onTouchEvent()—>ViewGroup的onTouchEvent()—>Activity的onTouchEvent()
3、dispatchTouchEvent()以及onTouchEvent()有一个共同点就是:当返回值为true时,则消费此次事件,不再传递给任何view
4、Activity的dispatchTouchEvent()不管返回true还是false都是消费掉事件,返回super.xxx的时候才会分发给下一级ViewGroup的dispatchTouchEvent(),ViewGroup的dispatchTouchEvent()返回false时,则事件回溯到父类(Activity)的onTouchEvent()处理。
5、ViewGroup的dispatchTouchEvent()返回super.xxx时,事件传递给自己的onInterceptTouchEvent()处理,如果onInterceptTouchEvent()返回true,表示拦截,然后交给自己的onTouchEvent()处理(onTouchEvent()返回true则消费掉事件,谁也接收不到此事件,返回false或者super.xxx时,则交给父类的onTouchEvent()处理),返回false或者super.xxx时会将事件交给下一级View的dispatchTouchEvent()处理。
6、View的dispatchTouchEvent()接收到事件之后,返回值为false,则回溯给父类(ViewGroup)的onTouchEvent()处理,返回值为super.xxx时,则交给自己的onTouchEvent()处理。onTouchEvent()返回true则消费掉事件,谁也接收不到此事件,返回false或者super.xxx时,则交给父类的onTouchEvent()处理。

建议对着下面的图再看


view_event.png

你可能感兴趣的:(Android事件分发流程详解)