分析这个这个拿笔在纸上画图是最好的方式,我是画的图。直接上图吧。
就是俺的诺基亚6500s拍照实在是不给力。
防止以后忘记没的复习,我用文字描述一下。
-----------------------------------------------------------------------分割线----------------------------------------------------------------------------------------------------------------------------------------------------
估计是描述不清楚的。我参考了这一篇博客:http://www.cnblogs.com/kingcent/archive/2011/03/08/1977059.html
事先声明这个大部分是原文,我是读了这位大牛的文章,然后加上自己调试程序得到的理解,再总结出来的。描述成自己能明白的形式。
-------------------------------------------------------------------------分割线—————————————————————————————————————————————————
首先,这篇文章仅仅针对于由于触摸(Touch)而触发的事件。
Android的事件:onClick, onScroll, onFling等等,都是由许多个Touch组成的。其中Touch的第一个状态肯定是ACTION_DOWN, 表示按下了屏幕。之后,touch将会有后续事件,可能是:
-
ACTION_MOVE //表示为移动手势(这个MOVE事件可能会与onLongClick()冲突,这个在源码中是利用速率来解决的)
-
ACTION_UP //表示为离开屏幕
-
ACTION_CANCEL //表示取消手势,不会由用户产生,而是由程序产生的
一个Action_DOWN, n个ACTION_MOVE, 1个ACTION_UP,就构成了Android中众多的事件。
在Android中,有一类控件是中还可以包含其他的子控件,这类控件是继承于ViewGroup类,例如:ListView, Gallery, GridView。
还有一类控件是不能再包含子控件,例如:TextView。
本文的主要讨论对象就是ViewGroup类的控件嵌套时事件触发情况。
Action_DOWN的传递过程,依次经过Activity—>实体视图(TextView,ImageView等)—>ViewGroup
各个层次关鉴方法是:
Activity:
@OverrideViewGroup:
public boolean dispatchTouchEvent(MotionEvent ev) {}
@Override
public boolean onTouchEvent(MotionEvent event) {}
@Override public boolean dispatchTouchEvent(MotionEvent ev) {} @Override public boolean onTouchEvent(MotionEvent event) {}
boolean onTouchEvent(MotionEvent event) {}
(实体)View:
public boolean dispatchTouchEvent(MotionEvent ev) {} setOnTouchListener(){} boolean onTouchEvent(MotionEvent event) {}
onClick()
onLongClick()
对于ViewGroup类的控件,有一个很重要的方法,就是onInterceptTouchEvent(),用于处理事件并改变事件的传递方向,它的返回值是一个布尔值,决定了Touch事件是否要向它包含的子View继续传递,这个方法是从父View向子View传递。
而方法onTouchEvent(),用于接收事件并处理,它的返回值也是一个布尔值,决定了事件及后续事件是否继续向上传递,这个方法是从子View向父View传递。
touch事件在 onInterceptTouchEvent()和onTouchEvent以及各个childView间的传递机制完全取决于onInterceptTouchEvent()和onTouchEvent()的返回值。返回值为true表示事件被正确接收和处理了(就是把这个事件给消费了,消费了就不再继续传递了),返回值为false表示事件没有被处理,将继续传递下去。
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_MOVE/ACTION_UP)只会传递给对于必要事件ACTION_DOWN返回了true的onTouchEvent)
总结一下就是:onInterceptTouchEvent可以接受到所有的Touch事件,而onTouchEvent则不一定。
其实这里面最重要的就是return的是true还是false。
返回了true,后续事件(ACTION_MOVE/ACTION_UP)只会传递给对于必要事件ACTION_DOWN返回了true的onTouchEvent。并且DOWN事件不会再向下传递。
下面一篇文章会详细解释这个返回值的问题。因为这个返回值是最重要的,事件处理的巧妙就是在这个返回值上。不知道理解的对不对,呵呵。