android之Touch事件处理机制



1.Android的事件有哪些?

onClick, onScroll, onFling等等,都是由许多个Touch组成的

2.Touch的第一个状态是什么顺序?

第一个状态肯定是   ACTION_DOWN, 表示按下了屏幕。之后,touch将会有后续事件,可能是:
ACTION_MOVE //表示为移动手势
ACTION_UP //表示为离开屏幕
ACTION_CANCEL //表示取消手势,不会由用户产生,而是由程序产生的
一个Action_DOWN, n个ACTION_MOVE, 1个ACTION_UP,就构成了Android中众多的事件。
3.ViewGroup类的控件嵌套时事件如何传递和处理?
android系统中的每个View的子类都具有下面三个和TouchEvent处理密切相关的方法:
1)public boolean dispatchTouchEvent(MotionEvent ev)  这个方法用来分发TouchEvent
2)public boolean onInterceptTouchEvent(MotionEvent ev) 这个方法用来拦截TouchEvent
3)public boolean onTouchEvent(MotionEvent ev) 这个方法用来处理TouchEvent

4.onInterceptTouchEvent()方法用来做什么?
对于ViewGroup类的控件,有一个很重要的方法,就是onInterceptTouchEvent(),用于处理事件并改变事件的传递方向,它的返回值是一个布尔值,决定了Touch事件是否要向它包含的子View继续传递,这个方法是从父View向子View传递。
5.onTouchEvent()方法用来做什么?
onTouchEvent(),用于接收事件并处理,它的返回值也是一个布尔值,决定了事件及后续事件是否继续向上传递,这个方法是从子View向父View传递
6.dispatchTouchEvent是负责分发事件
7.整个过程是怎么样的?
 dispatchTouchEvent是负责分发事件的,事件从 activity 传递出来之后,最先到达的就是最顶层 view 的 dispatchTouchEvent ,然后它进行分发,如果返回false ,则交给这个 view 的 interceptTouchEvent 方法来决定是否要拦截这个事件,如果 interceptTouchEvent 返回 true ,也就是拦截掉了,则交给它的 onTouchEvent 来处理,如果 interceptTouchEvent 返回 false ,那么就传递给子 view ,由子 view 的dispatchTouchEvent 再来开始这个事件的分发。
8.注意看我的例子是怎么重写的?必须调用surper方法,并且注意返回值
 
9.一个例子:要求最上层view先处理触摸事件,当最上层view不需要处理时,让子view来处理

需求:要做一个完全通过flip手势来切换的界面。在最上层用一个ViewFlipper作为容器,并检测flip手势操作。

难题:ViewFlipper的flip手势检测需要的MotionEvent,会被各种子View的触摸检测给拦截了。比如界面上有一个Button,则当手指按下Button(还没有抬起)然后flip出Button,最上层的flip手势检测是无效的。

原因:android对Touch Event的分发逻辑是View从上层分发到下层(dispatchTouchEvent函数),然后下层优先开始处理Event(先mOnTouchListener,再onTouchEvent)并向上返回处理情况(boolean值),下层若返回true,则上层不再处理。

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

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

     于是难题出现了,你若把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);       }

_flipDetector.onTouchEvent(event)这个可以根据需要返回值。

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


参考两篇比较好的文章

1.http://blog.csdn.net/starfeng11/article/details/7009338

2.http://blog.csdn.net/spt110/article/details/7919870


自己做测试的例子:

http://download.csdn.net/detail/fastthinking/7089909

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值