Android Touch事件处理机制

当TouchEvent发生时,首先Activity将TouchEvent传递给最顶层的View, TouchEvent最先到达最顶层 view 的 dispatchTouchEvent ,然后由  dispatchTouchEvent 方法进行分发,如果dispatchTouchEvent返回true ,则交给这个view的onTouchEvent处理,如果dispatchTouchEvent返回 false ,则交给这个 view 的 interceptTouchEvent 方法来决定是否要拦截这个事件,如果 interceptTouchEvent 返回 true ,也就是拦截掉了,则交给它的 onTouchEvent 来处理,如果 interceptTouchEvent 返回 false ,那么就传递给子 view ,由子 view 的 dispatchTouchEvent 再来开始这个事件的分发。如果事件传递到某一层的子 view 的 onTouchEvent 上了,这个方法返回了 false ,那么这个事件会从这个 view 往上传递,都是 onTouchEvent 来接收。而如果传递到最上面的 onTouchEvent 也返回 false 的话,这个事件就会“消失”,而且接收不到下一次事件。 

onTouch方法: 是View的onTouchListener接口中定义的方法,当View绑定了onTouchListener后,当有touch事件触发时,就会调用onTouch方法。

onTouchEvent方法: 是重写了Activity中的方法。

Android的Touch事件处理分3个层面:Activity层,ViewGroup层,View层
Touch事件处理的几条基本原则:
1.如果在某个层级没有处理ACTION_DOWN,那么该层就再也收不到后续的Touch事件了,直到下ACTION_DOWN事件
  说明:
    a.某个层级没有处理某个事件指的是它以及它的子View都没有处理该事件
    b.这条规则不适用于Activity层(它是顶层),他们可以收到每一个Touch事件。
    c.没有处理ACTION_MOVE这类事件,不会有任何影响

2.如果ACTION_DOWN事件发生在某个View的范围之内,则后续的ACTION_MOVE,ACTION_UP和ACTION_CANCEL等事件都将发往该View,即使事件已经出界了
3.第一根按下的手指触发ACTION_DOWN事件,之后按下的手指触发ACTION_POINTER_DOWN事件,中间起来的手指触发ACTION_POINTER_UP事件,最后起来的手指触发ACTION_UP事件(即使它不是触发ACTION_DOWN事件的那根手指)。
4.pointer id可以跟踪手指,从按下的那个时刻起pointer id生效,直至起来的那一刻失效,这之间维持不变。
5.如果一个ACTION_DOWN事件被付View拦截了,则任何子View不会再收到任何Touch事件了(这符合第一点要求)
6.如果一个非ACTION_DOWN事件被父Vew拦截了,则那些上次处理了ACTION_DOWN事件的子View会收到一个ACTION_CANCEL事件,之后不会再收到任何Touch事件了,即使父View不再拦截后续的Touch事件。
7.如果父View决定处理Touch事件或者子View没有处理Touch事件,则父View按照普通View的处理方式处理Touch事件,否则它根本不处理Touch事件(它只负责分发)
8.如果父View在onInterceptTouchEvent中拦截事件,则onInterceptTouchEvent中不会再收到Touch事件了,事件被直接交给它自己处理


总结:

Android事件触发流程:

-------------------------------------------------------------------

首先触发ACTIVITY的dispatchTouchEvent

然后触发ACTIVITY的onUserInteraction

然后触发LAYOUT的dispatchTouchEvent

然后触发LAYOUT的onInterceptTouchEvent

-------------------------------------------------------------------

查看:http://hi.baidu.com/lck0502/blog/item/7eeb452a846ff196023bf654.html

=================================================================================================================

在ViewGroup(即上面Layout)情况特别分析:

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

如果 return true时,会传递给当前控件的onTouchEvent(),而不在传递给子控件,这就是所谓的Intercept(截断)。

如果return false;(默认是false)那么表示该方法并未完全处理,

这样才能把事件传给View里的onTouchEvent.

ViewGroup里的onTouchEvent默认值是false。

View里的onTouchEvent返回默认值是true.这样才能执行多次touch事件

由于onInterceptTouchEvent()的机制比较复杂,总结一下,基本的规则是:

1.       down事件首先会传递到onInterceptTouchEvent()方法

2.       如果该ViewGroup的onInterceptTouchEvent()在接收到down事件处理完成之后return false,那么后续的move, up等事件将继续会先传递给该ViewGroup,之后才和down事件一样传递给最终的目标view的onTouchEvent()处理。

3.       如果该ViewGroup的onInterceptTouchEvent()在接收到down事件处理完成之后return true,那么后续的move, up等事件将不再传递给onInterceptTouchEvent(),而是和down事件一样传递给该ViewGroup的onTouchEvent()处理,注意,目标view将接收不到任何事件。

4.       如果最终需要处理事件的view的onTouchEvent()返回了false,那么该事件将被传递至其上一层次的view的onTouchEvent()处理。(尼玛,return false时,向父View传递啊)

5.       如果最终需要处理事件的view 的onTouchEvent()返回了true,那么后续事件将可以继续传递给该view的onTouchEvent()处理。


而方法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类的控件,则传递给它的onTouchEvent。

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

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

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

以上摘录自:http://www.cnblogs.com/kingcent/archive/2011/03/08/1977059.html



  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值