Android ViewGroup中事件触发和传递机制

针对由于触摸(Touch)而触发的事件 。
的事件:, , 等等,都是由许多个Touch组成的 。其中Touch的第一个状态肯定是, 表示按下了屏幕 。之后,touch将会有后续事件,可能是:
//表示为移动手势
//表示为离开屏幕
//表示取消手势,不会由用户产生,而是由程序产生的
一个, n个, 1个,就构成了中众多的事件 。
在中,有一类控件是中还可以包含其他的子控件,这类控件是继承于类,例如:, ,。
还有一类控件是不能再包含子控件,例如: 。
本文的主要讨论对象就是类的控件嵌套时事件触发情况 。
对于类的控件,有一个很重要的方法,就是t(),用于处理事件并改变事件的传递方向,它的返回值是一个布尔值,决定了Touch事件是否要向它包含的子View继续传递,这个方法是从父View向子View传递 。
而方法(),用于接收事件并处理,它的返回值也是一个布尔值,决定了事件及后续事件是否继续向上传递,这个方法是从子View向父View传递 。
Touch事件在 t()和以及各个间的传递机制完全取决于t()和()的返回值 。返回值为true表示事件被正确接收和处理了,返回值为false表示事件没有被处理,将继续传递下去(只是传递方向不一样,t()向子View传,而()向父View传) 。
具体情况如下:
事件会传到某个类的t,如果返回false,则DOWN事件继续向子类的t传递,如果子View不是类的控件,则传递给子View的 。

Android ViewGroup中事件触发和传递机制

文章插图
如果t返回了true,则DOWN事件传递给的,不再继续传递,并且之后的后续事件也都传递给它的 。
如果某View的返回了false,则DOWN事件继续向其父类的传递;如果返回了true,则后续事件会直接传递给其继续处理 。(后续事件只会传递给对于必要事件返回了true的)
/`````````````````````````````````````````````````````````````````
以前写,对事件的处理没有太深入,只是简单的就ok了,现在写的UI,很多自定义组件,父view和子view都需要接收事件,然后处理 。如果不弄明白它的事件传递机制,很难拥有好的用户体验 。
中,返回值是true,则说明消耗掉了这个事件,返回值是false,则没有消耗掉,会继续传递下去,这个是最基本的 。
在View中跟Touch相关的事件有,,三种 。是负责分发事件的,事件从传递出来之后,最先到达的就是最顶层view的,然后它进行分发,如果返回false,则交给这个view的方法来决定是否要拦截这个事件,如果返回true,也就是拦截掉了,则交给它的来处理,如果返回false,那么就传递给子view,由子view的再来开始这个事件的分发 。
如果事件传递到某一层的子view的上了,这个方法返回了false,那么这个事件会从这个view往上传递,都是来接收 。而如果传递到最上面的也返回false的话,这个事件就会“消失”,而且接收不到下一次事件 。(我说的一次事件指的是down到up之间的一系列事件)
我画了个图,见附件 。
总结一下,如果这一次事件没有人消耗掉,则系统不会给你下一次事件,因为他会认为你这次的事件阻塞了,没必要给下一次 。如果不消耗的话,会从子view传递到父view 。
又一个例子:
需求:要做一个完全通过flip手势来切换的界面 。在最上层用一个作为容器,并检测flip手势操作 。
难题:的flip手势检测需要的会被各种子View的触摸检测给拦截了 。比如界面上有一个,则当手指按下(还没有抬起)然后flip出,则最上层的flip手势检测无效 。
原因:对Touch Event的分发逻辑是View从上层分发到下层(函数),然后下层优先开始处理Event(先,再)并向上返回处理情况(值),若返回true,则上层不再处理 。