`
iaiai
  • 浏览: 2144413 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

android touch事件的传递

 
阅读更多
针对由于触摸(Touch)而触发的事件。
Android的事件:onClick, onScroll, onFling等等,都是由许多个Touch组成的。其中Touch的第一个状态肯定是 ACTION_DOWN, 表示按下了屏幕。之后,touch将会有后续事件,可能是:
ACTION_MOVE //表示为移动手势
ACTION_UP //表示为离开屏幕
ACTION_CANCEL //表示取消手势,不会由用户产生,而是由程序产生的
一个Action_DOWN, n个ACTION_MOVE, 1个ACTION_UP,就构成了Android中众多的事件。
在Android中,有一类控件是中还可以包含其他的子控件,这类控件是继承于ViewGroup类,例如:ListView, Gallery, GridView。

还有一类控件是不能再包含子控件,例如:TextView。
本文的主要讨论对象就是ViewGroup类的控件嵌套时事件触发情况。
对于ViewGroup类的控件,有一个很重要的方法,就是onInterceptTouchEvent(),用于处理事件并改变事件的传递方向,它的返回值是一个布尔值,决定了Touch事件是否要向它包含的子View继续传递,这个方法是从父View向子View传递。而方法onTouchEvent(),用于接收事件并处理,它的返回值也是一个布尔值,决定了事件及后续事件是否继续向上传递,这个方法是从子View向父View传递。

Touch事件在 onInterceptTouchEvent()和onTouchEvent以及各个childView间的传递机制完全取决于onInterceptTouchEvent()和onTouchEvent()的返回值。返回值为true表示事件被正确接收和处理了,返回值为false表示事件没有被处理,将继续传递下去(只是传递方向不一样,onInterceptTouchEvent()向子View传,而onTouchEvent()向父View传)。

具体情况如下:
ACTION_DOWN事件会传到某个ViewGroup类的onInterceptTouchEvent,如果返回false,则DOWN事件继续向子ViewGroup类的onInterceptTouchEvent传递,如果子View不是ViewGroup类的控件,则传递给子View的onTouchEvent。

如果onInterceptTouchEvent返回了true,则DOWN事件传递给VIewGroup的onTouchEvent,不再继续传递,并且之后的后续事件也都传递给它的onTouchEvent。

如果某View的onTouchEvent返回了false,则DOWN事件继续向其父ViewGroup类的onTouchEvent传递;如果返回了true,则后续事件会直接传递给其onTouchEvent继续处理。(后续事件只会传递给对于必要事件ACTION_DOWN返回了true的onTouchEvent)

以前写 android ,对事件的处理没有太深入,只是简单的 onTouchEvent 就 ok 了,现在写的 UI ,很多自定义组件,父 view 和子view 都需要接收事件,然后处理。如果不弄明白它的事件传递机制,很难拥有好的用户体验。
Touchevent 中,返回值是 true ,则说明消耗掉了这个事件,返回值是 false ,则没有消耗掉,会继续传递下去,这个是最基本的。

在 View 中跟 Touch 相关的事件有 dispatchTouchEvent , interceptTouchEvnet , onTouchEvent 三种。 dispatchTouchEvent是负责分发事件的,事件从 activity 传递出来之后,最先到达的就是最顶层 view 的 dispatchTouchEvent ,然后它进行分发,如果返回false ,则交给这个 view 的 interceptTouchEvent 方法来决定是否要拦截这个事件,如果 interceptTouchEvent 返回 true ,也就是拦截掉了,则交给它的 onTouchEvent 来处理,如果 interceptTouchEvent 返回 false ,那么就传递给子 view ,由子 view 的dispatchTouchEvent 再来开始这个事件的分发。
如果事件传递到某一层的子 view 的 onTouchEvent 上了,这个方法返回了 false ,那么这个事件会从这个 view 往上传递,都是onTouchEvent 来接收。而如果传递到最上面的 onTouchEvent 也返回 false 的话,这个事件就会“消失”,而且接收不到下一次事件。(我说的一次事件指的是 down 到 up 之间的一系列事件)
我画了个图,见附件。

总结一下,如果这一次事件没有人消耗掉,则系统不会给你下一次事件,因为他会认为你这次的事件阻塞了,没必要给下一次。onTouchEvent如果不消耗的话,会从子view传递到父view。

又一个例子:
需求:要做一个完全通过flip手势来切换的界面。在最上层用一个ViewFlipper作为容器,并检测flip手势操作。
难题:ViewFlipper的flip手势检测需要的MotionEvent会被各种子View的触摸检测给拦截了。比如界面上有一个Button,则当手指按下Button(还没有抬起)然后flip出Button,则最上层的flip手势检测无效。
原因:android对Touch Event的分发逻辑是View从上层分发到下层(dispatchTouchEvent函数),然后下层优先开始处理Event(先mOnTouchListener,再onTouchEvent)并向上返回处理情况(boolean值),若返回true,则上层不再处理。

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

开始仅着眼于Touch Event处理完后的回传过程,想了N久不得,毕竟我想实现的是一个需要打破android事件处理逻辑的效果(就是一个连续性操作,只有不满足上层要求时,才轮到下层处理)。然后突然想到事件的分发过程,便豁然开朗:
覆写最上层的View的dispatchTouchEvent函数,代码如下:
@Override
  public boolean dispatchTouchEvent(MotionEvent event) {
         if (_flipDetector.onTouchEvent(event)) {
                 event.setAction(MotionEvent.ACTION_CANCEL);
         }
         return super.dispatchTouchEvent(event);
  }

于是效果实现。也就是在分发之前便进行手势检测处理,若检测成功,则取消下层的一切处理过程。
总结一下就是:onInterceptTouchEvent可以接受到所有的Touch事件,而onTouchEvent则不一定。
  • 大小: 48.4 KB
分享到:
评论

相关推荐

    android Touch事件传递机制

    android Touch事件传递机制的实例

    Android Touch事件传递机制解析

    Android Touch事件传递机制解析

    AndroidTouch事件传递机制解析

    开篇语:最近程序在做一个小效果,要用到touch,结果整得云里面雾里的,干脆就好好把android touch机制好好看了一下,呵呵。。android系统中的每个ViewGroup的子类都具有下面三个和TouchEvent处理密切相关的方法:1...

    Android中Touch事件的传递

    从布局的角度来分析Touch事件,便于深刻的理解并编写出合理代码。

    android之Touch事件处理机制测试

    android之Touch事件处理机制测试, 滑动事件冲突解决,ViewGroup中事件触发和传递机制

    android 事件传递demo

    简单的android事件传递demo,对touch事件分发进行测试

    Android中touch事件传递测试demo

    onInterceptTouchEvent和onTouchEvent调用时序详解 测试demo 详细介绍请移步:http://blog.csdn.net/yiranxinshou/article/details/9201833

    android事件分发机制

    Android中的事件类型分为按键事件和屏幕触摸事件,Touch事件是屏幕触摸事件的基础事件,有必要对它进行深入的了解。

    android事件分发机制测试demo

    安卓事件分发机制测试代码,事件传递从Activity-->ViewGroup-->View。dispatchTouchEvent,onInterceptTouchEvent,onTouchEvent这三个函数的返回值不同,代表的事件传递的不同。

    TouchDemo2.zip

    Touch事件传递机制分析Demo,展示dispatchTouchEvent(),onInterceptTouchEvent(),onTouchEvent()的事件传递顺序。使用方法:安装,连接androidstudio看logcat

    itgoyo#AndroidSource-Analysis#公共技术点之View事件传递1

    (1) 所有 Touch 事件都被封装成了 MotionEvent 对象,包括 Touch 的位置、时间、历史记录以及第几个手指(多指触摸)等 (2) 事件类型

    详细分析Android中onTouch事件传递机制

    相信不少朋友在刚开始学习Android的时候,对于onTouch相关的事件一头雾水。分不清onTouch(),onTouchEvent()和OnClick()之间的关系和先后顺序,所以觉得有必要搞清onTouch事件传递的原理。经过一段时间的琢磨以及...

    Android开发艺术探索.任玉刚(带详细书签).pdf

    3.4.1 点击事件的传递规则 140 3.4.2 事件分发的源码解析 144 3.5 View的滑动冲突 154 3.5.1 常见的滑动冲突场景 155 3.5.2 滑动冲突的处理规则 156 3.5.3 滑动冲突的解决方式 157 第4章 View的工作原理 174 ...

    Android开发艺术探索

    3.4.1 点击事件的传递规则 / 140 3.4.2 事件分发的源码解析 / 144 3.5 View的滑动冲突 / 154 3.5.1 常见的滑动冲突场景 / 155 3.5.2 滑动冲突的处理规则 / 156 3.5.3 滑动冲突的解决方式 / 157 第4章 ...

    android开发艺术探索高清完整版PDF

    / 133 3.2.4 各种滑动方式的对比 / 133 3.3 弹性滑动 / 135 3.3.1 使用Scroller / 136 3.3.2 通过动画 / 138 3.3.3 使用延时策略 / 139 3.4 View的事件分发机制 / 140 3.4.1 点击事件的传递规则 / 140 3.4.2...

    javalruleetcode-Android-interview-knowledge:Android-面试知识

    事件传递 2. ListView 的优化 3. Android内序列化的方式 4. 广播的几种方式 5. service生命周期,启动方式,优点,用途 6. 进程的优先级 7. view的绘制过程 8. android 实现异步调用的几种方式。 9. handler实现 10....

Global site tag (gtag.js) - Google Analytics