首页 >> 大全

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

2023-09-28 大全 24 作者:考证青年

针对由于触摸(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的。

d触发器传输门__触发器可以传递参数

如果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,则上层不再处理。

于是我们首先想到,要保证flip手势检测,需要把所有的Touch Event都传到上层去。

然而在分发逻辑之外还有一个逻辑,估计是为了保证每个触操作只能由一个View来进行完整响应,对事件有个额外的逻辑:如果某个View在处理事件时返回false(即该View未处理此事件),那么后续产生的其它事件将直接忽略掉这个View(不过又有另外的独立逻辑)。举例来说就是,如果你处理时返回了false,那么你这个View将得不到或等等这些后续事件了。

于是难题出现了,你若把Touch Event都想办法给传到上层了(只能通过返回false来传到上层),那么下层的各种子View就不能处理后续事件了。

解决方案:

开始仅着眼于Touch Event处理完后的回传过程,想了N久不得,毕竟我想实现的是一个需要打破事件处理逻辑的效果(就是一个连续性操作,只有不满足上层要求时,才轮到下层处理)。然后突然想到事件的分发过程,便豁然开朗:

覆写最上层的View的函数,代码如下:

@

( event) {

if (.(event)) {

event.(.);

super.(event);

于是效果实现。也就是在分发之前便进行手势检测处理,若检测成功,则取消下层的一切处理过程。

总结一下就是:t可以接受到所有的Touch事件,而则不一定。

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了