6、ViewGroup和View的dispatchTouchEvent方法返回super.dispatchTouchEvent()的时候事件流走向。
图6
首先看下ViewGroup的dispatchTouchEvent,之前说的return true是终结传递。return false是回溯到父View的onTouchEvent,然后ViewGroup怎样通过dispatchTouchEvent方法能把事件分发到自己的onTouchEvent处理呢,return true和false都不行,那么只能通过Interceptor把事件拦截下来给自己的onTouchEvent,所以ViewGroup dispatchTouchEvent方法的super默认实现就是去调用onInterceptTouchEvent,记住这一点。
那么对于View的dispatchTouchEvent return super.dispatchTouchEvent()的时候呢事件会传到哪里呢,很遗憾View没有拦截器。但是同样的道理return true是终结。return false是回溯会父类的onTouchEvent,怎样把事件分发给自己的onTouchEvent处理呢,那只能return super.dispatchTouchEvent,View类的dispatchTouchEvent()方法默认实现就是能帮你调用View自己的onTouchEvent方法的。
说了这么多,不知道有说清楚没有,我这边最后总结一下:
对于dispatchTouchEvent,onTouchEvent,return true是终结事件传递。return false是回溯到父View的onTouchEvent方法。
ViewGroup想把自己分发给自己的onTouchEvent,需要拦截器onInterceptTouchEvent方法return true把事件拦截下来。
ViewGroup的拦截器onInterceptTouchEvent默认是不拦截的,所以return super.onInterceptTouchEvent()=return false;
View没有拦截器,为了让View可以把事件分发给自己的onTouchEvent,View的dispatchTouchEvent默认实现(super)就是把事件分发给自己的onTouchEvent。
ViewGroup和View的dispatchTouchEvent是做事件分发,那么这个事件可能分发出去的四个目标
注:——>后面代表事件目标需要怎么做。
1、自己消费,终结传递。——->return true;
2、给自己的onTouchEvent处理——->调用super.dispatchTouchEvent()系统默认会去调用onInterceptTouchEvent,在onInterceptTouchEvent return true就会去把事件分给自己的onTouchEvent处理。
3、传给子View——>调用super.dispatchTouchEvent()默认实现会去调用onInterceptTouchEvent在onInterceptTouchEvent return false,就会把事件传给子类。
4、不传给子View,事件终止往下传递,事件开始回溯,从父View的onTouchEvent开始事件从下到上回归执行每个控件的onTouchEvent——->return false;
注:由于View没有子View所以不需要onInterceptTouchEvent来控件是否把事件传递给子View还是拦截,所以View的事件分发调用super.dispatchTouchEvent()的时候默认把事件传给自己的onTouchEvent处理(相当于拦截),对比ViewGroup的dispatchTouchEvent事件分发,View的事件分发没有上面提到的4个目标的第3点。
ViewGroup和View的onTouchEvent方法是做事件处理的,那么这个事件只能有两个处理方式:
1、自己消费掉,事件终结,不再传给谁—–>return true;
2、继续从下往上传,不消费事件,让父View也能收到到这个事件—–>return false;View的默认实现是不消费的。所以super==false。
ViewGroup的onInterceptTouchEvent方法对于事件有两种情况:
1、拦截下来,给自己的onTouchEvent处理—>return true;
2、不拦截,把事件往下传给子View—->return false,ViewGroup默认是不拦截的,所以super==false;
关于ACTION_MOVE和ACTION_UP
上面讲解的都是针对ACTION_DOWN的事件传递,ACTION_MOVE和ACTION_UP在传递的过程中并不是和ACTION_DOWN一样,你在执行ACTION_DOWN的时候返回了false,后面一系列其它的action就不会再得到执行了。简单的说,就是当dispatchTouchEvent在进行事件分发的时候,只有前一个事件(如ACTION_DOWN)返回true,才会收到ACTION_MOVE和ACTION_UP的事件。具体这句话很多博客都说了,但是具体含义是什么呢?我们来看一下下面的具体分析。
上面提到过了,事件如果不被打断的话是会不断往下传到叶子层(View),然后又不断回传到Activity,dispatchTouchEvent和onTouchEvent可以通过return true消费事件,终结事件传递,而onInterceptTouchEvent并不能消费事件,它相当于是一个分叉口起到分流导流的作用,ACTION_MOVE和ACTION_UP会在哪些函数被调用,之前说了并不是哪个函数收到了ACTION_DOWN,就会收到ACTION_MOVE等后续的事件的。
下面通过几张图看看不同场景下,ACTION_MOVE事件和ACTION_UP事件的具体走向并总结一下规律。
1、我们在ViewGroup1的dispatchTouchEvent方法返回true消费这次事件
ACTION_DOWN事件从(Activity的dispatchTouchEvent)——–>(ViewGroup1的dispatchTouchEvent)后结束传递,事件被消费(如下图红色的箭头代码ACTION_DOWN事件的流向)。
//打印日志
Activity | dispatchTouchEvent --> ACTION_DOWN
ViewGroup1 | dispatchTouchEvent --> ACTION_DOWN
---->消费
本文来源:不详 作者:佚名