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
---->消费
在这种场景下ACTION_MOVE和ACTION_UP将如何呢,看下面的打出来的日志
Activity | dispatchTouchEvent --> ACTION_MOVE
ViewGroup1 | dispatchTouchEvent --> ACTION_MOVE
----
TouchEventActivity | dispatchTouchEvent --> ACTION_UP
ViewGroup1 | dispatchTouchEvent --> ACTION_UP
----
下图中
红色的箭头代表ACTION_DOWN事件的流向
蓝色的箭头代表ACTION_MOVE和ACTION_UP事件的流向
Paste_Image.png
2、我们在ViewGroup2的dispatchTouchEvent返回true消费这次事件
Activity | dispatchTouchEvent --> ACTION_DOWN
ViewGroup1 | dispatchTouchEvent --> ACTION_DOWN
ViewGroup1 | onInterceptTouchEvent --> ACTION_DOWN
ViewGroup2 | dispatchTouchEvent --> ACTION_DOWN
---->消费
Activity | dispatchTouchEvent --> ACTION_MOVE
ViewGroup1 | dispatchTouchEvent --> ACTION_MOVE
ViewGroup1 | onInterceptTouchEvent --> ACTION_MOVE
ViewGroup2 | dispatchTouchEvent --> ACTION_MOVE
----
TouchEventActivity | dispatchTouchEvent --> ACTION_UP
ViewGroup1 | dispatchTouchEvent --> ACTION_UP
ViewGroup1 | onInterceptTouchEvent --> ACTION_UP
ViewGroup2 | dispatchTouchEvent --> ACTION_UP
----
红色的箭头代表ACTION_DOWN事件的流向
蓝色的箭头代表ACTION_MOVE和ACTION_UP事件的流向
Paste_Image.png