掌握Android Touch事件机制

DaveSmith

@devunwired

要点涵盖

l  Touch系统概述

l  Framwork层的Touch事件

l  Touch事件的处理

l  系统提供的TouchHandlers

l  系统提供的GestureHandlers

Android系统怎么处理Touch事件?

l  每一个touch事件都被封装成一个MotionEvent对象

l  这个对象描述了用户当前的动作

– ACTION_DOWN

– ACTION_UP

– ACTION_MOVE

–ACTION_POINTER_DOWN

–ACTION_POINTER_UP

– ACTION_CANCEL

l  事件元数据包括

– 触摸的位置

– 触摸点的个数(或触摸手指的根数)

– 事件发生的时间

l  一个“手势(gesture)”是以ACTION_DOWN开始,以ACTION_UP结束的

l  事件开始于Activity的dispatchTouchEvent()函数(看名字就知道这是对事件进行分发的)

l  事件在views之间依次传递

– 父view(ViewGroups)将事件传递给他的子view

– 事件在传递过程中可以随时被拦截

l  事件会在“传递链”中流动,直到回到Activity中,除非在流动的过程中被消费掉了

l  所有没有被消费的事件最终会回到Activity的onTouchEvent(),并结束传递。

l  外部定义的OnTouchListener能在任何View/ViewGroup中拦截事件,该接口的实现是可选的,即可以实现也可以不实现该接口。

l  Activity.dispatchTouchEvent()

–  总是第一个被调用。

–  将事件派送给Windows的根视图(Root View)

–  onTouchEvent()

l  如果没有View消费事件,该函数最终会被调用

l  总是最后一个被调用的函数。

l  View.dispatchTouchEvent()

–  如果注册了View.OnTouchListener,首先会将事件传递给它处理,调用:

l  View.onTouchListener.onTouch()

–  如果没有被消费,View会自己处理,调用:

l  View.onTouchEvent()

l  ViewGroup.dispatchTouchEvent()

–  onInterceptTouchEvent()

l  检查是否要拦截事件,不再传递给子View

l  但是会将ACTION_CANCEL事件传递给activechild

l  一旦消费掉随后而来的所有事件,该函数就会返回true

–  对于每个子View,按照他们被添加的顺序的反序,进行如下操作:

l  如果touch事件是有意义的(即在View内),调用子view的dispatchTouchEvent();

l  如果事件没有被处理,便将事件传递给下一个View。

–  如果没有一个子view处理了事件,便交给ViewGroup的OnTouchListener(如果定义了)处理,调用:

l  OnTouchListener.onTouch()

–  如果没有定义OnTouchListener或者OnTouchListener没有处理,调用:

l  onTouchEvent()

n  被拦截的事件会跳过子view的处理步骤。

n  一些例子

没有view处理事件时的传递流程

 

有view处理事件时的传递流程

 

ViewGroup拦截事件时的传递流程

Touch事件处理

l  如何处理Touch事件

–子类复写(override)父类的onTouchEvent()函数

– 实现OnTouchListener接口

l  消费事件

– ACTION_DOWN时返回true,以表示你对该事件感兴趣

l  即使你不对ACTION_DOWN感兴趣,也返回true

– 对于其他事件,返回true即中断了该事件的继续传递

l  ViewConfiguration中一些有用的方法

– getScaledTouchSlop()

表示一段距离,只有当手移动的距离≥该距离以后才会被认为是一个move事件

getScaledMinimumFlingVelocity()

表示一个速度,当手滑动的数据≥该速度的时候才会被认为是一个fling事件

–getLongPressTimeout()

表示一段时间,当超过点击事件≥该时间后才会被认为是一个long-press事件

– 显示每个设备的设备密度值

l  触发Touch事件的“流动”

– 调用dispatchTouchEvent()

– 不要直接调用onTouchEvent()

类似的,调用requestLayout()而非onLayout();调用invalidate()而非onDraw();调用performClick()而非onClick()(译者注);

l  拦截Touch事件(针对ViewGroup)

– 子类复写(override)父类的onInterceptTouchEvent()函数

– 当你想拦截事件时return true

针对当前操作(currentgesture)的所有事件都会直接进入你的OnTouchEvent()

针对所有这些事件onInterceptTouchEvent()也不会再被调用

– 当前所有目标(View和Activity)会接到ACTION_CANCEL事件

l  尽可能调用super.onTouchEvent()

– View.onTouchEvent()做了很多工作来维护状态(pressed、checked等),如果你自己处理了这些事件,你会丢失很多的处理工作。

l  对ACTION_MOVE事件做边界检查(Protect   ACTION_MOVE with slop checks)

– 因为手指操作毕竟不精细(Fingers arefat          and  twitchy)

l  总是记得处理ACTION_CANCEL

– 一些容器类View(例如ScrollView)会拦截事件,因此你需要处理ACTION_CANCEL来重置状态

– 记住,处理完ACTION_CANCEL后,不会再有其他事件了。

多点触控

l  MotionEvent.getPointerCount()

— 返回当前时刻屏幕上有多少触摸点

l  使用ACTION_POINTER_DOWN和ACTION_POINTER_UP来监听有多少个“二次触摸点”。

–  MotionEvent.ACTION_POINTER_DOWN:当屏幕上已经有一个点被按住,此时再按下其他点时触发。

– MotionEvent.ACTION_POINTER_UP:当屏幕上有多个点被按住,松开其中一个点时触发(即非最后一个点被放开时)。

–MoEonEvent.getAcEonMasked()

–MoEonEvent.getAcEonIndex()

批处理

l  为了提高效率,ACTION_MOVE事件可以放在一个MotionEvent中进行统一处理

l  标准的函数总是返回最近(当前)的事件。

如:getX(),getY(),getEventTime()只返回最近(当前)事件的X坐标,Y坐标和事件发生时间。

l  发生在ACTION_MOVE和最后一次事件之间的事件可以在历史方法(historical method)中得到

– getHistoricalX(),         getHistoricalY(),       getHistoricalEventTime()

– getHistoricalSize()     返回进行统一批处理的事件个数

系统封装好的Touch事件处理对象

l  常用的有:

? OnClickListener

? OnLongClickListener

? OnTouchListener

— 一个listener能监视一个单一的事件

—一个listene能够消费一个/些事件

l  OnScrollListener/View.onScrollChanged()

— 具有滑动功能的view滑动时调用的函数

l  针对更复杂的Touch事件,有如下的对象

GestureDetector

– onDown()

– onSingleTapUp()

– onDoubleTap()

– onLongPress()

– onScroll()

– onFling()

ScaleGestureDetector

– onScaleBegin()

–  onScale(),

– onScaleEnd()

以上的操作本质上都是通过OnTouchListener()和OnTouchEvent()来实现的

缺点

– 消费了Up事件,且没有暴露处理CANCEL事件的接口

委托Touch

Android 允许使用TouchDelegate来扩展Touch事件的响应区域。

使用方法:

ViewGroup parent;//父View

View child;//期望委托的子View

Rect touchArea;//委托Touch区域

parent.setTouchDelegate( newTouchDelegate(touchArea, child) );

原文链接http://wugengxin.cn/download/pdf/android/PRE_andevcon_mastering-the-android-touch-system.pdf

时间: 2024-10-07 15:58:46

掌握Android Touch事件机制的相关文章

Android touch 事件传递机制

前言: (1)在自定义view的时候经常会遇到事件拦截处理,比如在侧滑菜单的时候,我们希望在侧滑菜单里面有listview控件,但是我们希望既能左右滑动又能上下滑动,这个时候就需要对触摸的touch事件进行拦截.这个时候我们就需要明白android touch 事件传递机制, (2)以前很多时候比较模糊,也许是网上看到也有很多事件传递的相关文章,但我看着头晕,解释不彻底,有的说得一半,总算不满足不满意,于是据我自己的理解来彻底的来整理下具体的是怎么个传递方式,分享给大家,希望大家看到有什么不对的

【转】Android Touch事件传递机制解析

原文地址:http://www.cnblogs.com/runssnail/p/4250549.html 说明:本文在原文地址上有所改动 一.小故事 在讲正题之前我们讲一段有关任务传递的小故事,抛砖迎玉下: 话说一家软件公司,来一个任务,分派给了开发经理去完成 开发经理拿到,看了一下,感觉好简单,于是 开发经理:分派给了开发组长 开发组长:分派给了自己组员(程序员) 程序员:分派给了自己带的实习生. 实习生:好苦逼,无法分派,怎么办啊?只能自己干了 但是实习生能不能做好,有两种情况了. 情况一:

Android Touch事件传递机制详解 上

尊重原创:http://blog.csdn.net/yuanzeyao/article/details/37961997 最近总是遇到关于Android Touch事件的问题,如:滑动冲突的问题,以前也花时间学习过Android Touch事件的传递机制,可以每次用起来的时候总是忘记了,索性自己总结一下写篇文章避免以后忘记了,其实网上关于Touch事件的传递的文章真的很多,但是很少有系统性的,都是写了一个简单的demo运行了一下,对于我们了解Android Touch事件基本上没有任何帮助. 今

Android Touch事件传递机制引发的血案

尊重原创:http://blog.csdn.net/yuanzeyao/article/details/38942135 关于Android Touch事件传递机制我之前也写过两篇文章,自觉得对Touche事件还是理解得比較清楚的,可是近期遇到的一个问题,让我再次对Android Touche事件进行一次学习. 我的关于Android Touche事件传递机制的文章例如以下: http://blog.csdn.net/yuanzeyao/article/details/37961997 http

Android Touch事件传递机制 二:单纯的(伪生命周期)

转载于:http://blog.csdn.net/yuanzeyao/article/details/38025165 在前一篇文章中,我主要讲解了Android源码中的Touch事件的传递过程,现在我想使用一个demo以及一个实例来学习一下Andorid中的Touch事件处理过程. 在Android系统中,和Touch事件分发和处理紧密相关的三个函数如下:(1) public boolean dispatchTouchEvent(MotionEvent ev)(2) public boolea

Android Touch事件传递机制详解 下

尊重原创:http://blog.csdn.net/yuanzeyao/article/details/38025165 资源下载:http://download.csdn.net/detail/yuanzeyao2008/7660997 在前一篇文章中,我主要讲解了Android源码中的Touch事件的传递过程,现在我想使用一个demo以及一个实例来学习一下Andorid中的Touch事件处理过程. 在Android系统中,和Touch事件分发和处理紧密相关的三个函数如下:(1) public

Android Touch事件传递机制通俗讲解

在讲正题之前我们讲一段有关任务传递的小故事,抛砖迎玉下: 话说一家软件公司,来一个任务,分派给了开发经理去完成: 开发经理拿到,看了一下,感觉好简单,于是 开发经理:分派给了开发组长 开发组长:分派给了自己组员(程序员) 程序员:分派给了自己带的实习生. 实习生:好苦逼,无法分派,怎么办啊?只能自己干了 但是实习生能不能做好,有两种情况了. 情况一: 实习生:经过一段时间的研究,琢磨,熬夜,奋斗,死敲,皇天不负有心人啊,完成了. 后来又来一个类似的任务,也按着这样传递下去了(开发经理->开发组长

(转)Android Touch事件传递机制

-----来源:http://www.trinea.cn/android/touch-event-delivery-mechanism/ 介绍Android Touch事件的传递机制. 不少朋友私信问到这个问题,那就推荐一篇我看到的对传递机制介绍最清楚的国外文章吧.本文略作翻译. 1.基础知识 (1) 所有Touch事件都被封装成了MotionEvent对象,包括Touch的位置.时间.历史记录以及第几个手指(多指触摸)等. (2) 事件类型分为ACTION_DOWN, ACTION_UP, A

React-Native系列Android——Touch事件原理及状态效果

Native原生相比于Hybrid或H5最大优点是具有流畅和复杂的交互效果,触摸事件便是其中重要一项,包括点击(Click).长按(LongClick).手势(gesture)等. 以最简单常见的点击(Click)为例,Native组件可以自定义selector,使得被点击的组件具有动态效果,Android 5.0以上甚至可以有涟漪效果(Material Design).而这些在Hybrid或H5中很难实现,很多时候区分它们与原生最简单的方法就是检验点击交互效果. React-Native的强大