首页 » Android » Android 事件分发机制之一二三

Android 事件分发机制之一二三

原文 http://blog.csdn.net/CallmeZhe/article/details/79203533

2018-02-04 02:00:47阅读(252)

<a href=Android 事件分发机制之一二三" src="http://img.blog.csdn.net/20180130110743254?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvQ2FsbG1lWmhl/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" align="middle">

Android 事件分发流

 话不多说,先上一张图来了解下:

Android 事件分发机制之一二三

事件从左上角白色箭头开始,由Activity的dispatchTouchEvent做分发

箭头上面的字代表方法返回值

dispatchTouchEvent和 onTouchEvent的框里有个【true---->消费】的字,表示的意思是如果方法返回true,那么代表事件就此消费,不会继续往别的地方传了,事件终止

目前所有的图的事件是针对ACTION_DOWN的,对于ACTION_MOVE和ACTION_UP我们最后做分析

仔细看整个图,我们得出事件流 走向的几个结论

1、如果事件不被中断,整个事件流向是一个类U型图,我们来看下这张图,可能更能理解U型图的意思。

Android 事件分发机制之一二三

所以如果我们没有对控件里面的方法进行重写或更改返回值,而直接用super调用父类的默认实现,那么整个事件流向应该是从Activity---->ViewGroup--->View从上往下调用dispatchTouchEvent方法,一直到叶子节点(View)的时候,再由View--->ViewGroup--->Activity从下往上调用onTouchEvent方法。

2.dispatchTouchEvent 和 onTouchEvent 一旦return true,事件就停止传递了

Android 事件分发机制之一二三

3.dispatchTouchEvent 和 onTouchEvent return false的时候事件都回传给父控件的onTouchEvent处理。

Android 事件分发机制之一二三

看上图深蓝色的线,对于返回false的情况,事件都是传给父控件onTouchEvent处理。对于onTouchEvent return false 就比较简单了,它就是不消费事件,并让事件继续往父控件的方向从下往上流动。

4、dispatchTouchEvent、onTouchEvent、onInterceptTouchEvent 在ViewGroup 和View的这些方法的默认实现就是会让整个事件安装U型完整走完,所以 return super.xxxxxx() 就会让事件依照U型的方向的完整走完整个事件流动路径),中间不做任何改动,不回溯、不终止,每个环节都走到。

Android 事件分发机制之一二三

所以如果看到方法return super.xxxxx() 那么事件的下一个流向就是走U型下一个目标。

5、onInterceptTouchEvent 的作用

Android 事件分发机制之一二三

Intercept的意思就拦截,每个ViewGroup每次在做分发的时候,问一问拦截器要不要拦截,如果要自己处理那就在onInterceptTouchEvent方法中 return true就会交给自己的onTouchEvent的处理,如果不拦截就是继续往子控件往下传。默认是不会去拦截的,因为子View也需要这个事件,所以onInterceptTouchEvent拦截器return super.onInterceptTouchEvent()和return false是一样的,是不会拦截的,事件会继续往子View的dispatchTouchEvent传递。

6、ViewGroup 和View 的dispatchTouchEvent方法返回super.dispatchTouchEvent()的时候事件流走向。

Android 事件分发机制之一二三

首先看下ViewGroup的dispatchTouchEvent,之前说的return true是终结传递。return false是回溯到父View的onTouchEvent,然后ViewGroup怎样通过dispatchTouchEvent方法能把事件分发到自己的onTouchEvent处理呢,return true和false都不行,那么只能通过Interceptor把事件拦截下来给自己的onTouchEvent,所ViewGroupdispatchouchEvent方法的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方法是做事件处理的,那么这个事件只能有两个处理方式:

自己消费掉,事件终结,不再传给谁----->return true;
继续往上传,不消费事件,让父View也能收到到这个事件----->returnfalse;View的默认实现是不消费的。所以super==false。

ViewGroup的onInterceptTouchEvent方法对于事件有两种情况:

拦截下来,给自己的onTouchEvent处理--->return true;不拦截,把事件往下传给子View---->return false,ViewGroup默认是不拦截的,所以super==false;

下面来说下ACTION_MOVE 和 ACTION_UP

在执行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事件的具体走向并总结一下规律。

Android 事件分发机制之一二三

1、我们在ViewGroup1 的dispatchTouchEvent 方法返回true消费这次事件

ACTION_DOWN 事件从(Activity的dispatchTouchEvent)--------> (ViewGroup1 的dispatchTouchEvent) 后结束传递,事件被消费(如上图红色的箭头代码ACTION_DOWN 事件的流向)。

Activity | dispatchTouchEvent --> ACTION_MOVE 
ViewGroup1 | dispatchTouchEvent --> ACTION_MOVE
----
TouchEventActivity | dispatchTouchEvent --> ACTION_UP 
ViewGroup1 | dispatchTouchEvent --> ACTION_UP
----        

最新发布

CentOS专题

关于本站

5ibc.net旗下博客站精品博文小部分原创、大部分从互联网收集整理。尊重作者版权、传播精品博文,让更多编程爱好者知晓!

小提示

按 Ctrl+D 键,
把本文加入收藏夹