在Android中,人们主要经过手指与系统交互。Android把全部的touch事件都被封装成MotionEvent来进行处理,其中包括了手指点击的位置,时间等信息。其事件类型主要包括:ACTION_DOWN,ACTION_UP,ACTION_MOVE, ACTION_POINTER_DOWN, ACTION_POINTER_UP,ACTION_CANCEL。函数
这些事件是有触发顺序的,下面举两个栗子:spa
为了处理这些事件,Android定义了三种方法:blog
当一个事件被触发,事件的传递从Activity.dispatchTouchEvent()开始,一直从最外层的父view开始向里面的子view传递,直到被拦截。在传递过程当中,view能够经过onInterceptTouchEvent()函数进行拦截,一旦父view拦截了该事件,则再也不向下传递。事件
若是被触发的事件被传递至最内层的view,一直未被拦截消费,则会反向向外传递,这时候父view能够经过onTouchEvent函数对事件进行消费,直到activity。另外,若是被触发的ACTION_DOWN事件在某一层未被消费,那么接下来的事件是没法被传递进来的。开发
下面咱们来看几个例子:it
Case 1 手指点击在view上,父View(ViewGroup)和View都不消费事件,最终返回给activity消费。io
以ACTION_DOWN事件为例,ACTION_DOWN事件沿着图中黑色箭头逐层传递。在开发过程当中,咱们一般会为view或者viewGroup设置监听器来捕获view事件,listener的onTouch方法会在onTouchEvent以前执行。在分发传递过程当中,不管哪一个方法返回true,都表示传递中止;若是返回false,则表示继续传递下去。event
从图上能够看出,ACTION_DOWN事件通过activity—>ViewGroup—>View—>ViewGroup—>activity一直未被ViewGroup和View消费处理,又回到了activity中。那么随后的ACTION_MOVE和ACTION_UP事件只会沿着绿色箭头传递,再也不沿着ACTION_DOWN事件的路线传递了。List
Case 2 手指点击在父View和子View之间的空隙中,并未点击在子View上。同上一个例子同样,ViewGroup中并未消费该事件,返回给了activity。方法
这里用户并未点击到ViewGroup中的view,而是点击在了ViewGroup和View之间的空隙处。同上一个例子相同,ViewGroup并未处理ACTION_DOWN事件,而是返回给了activity处理。
Case 3 单击view后,在view中处理消费了ACTION_DOWN事件。
从图上能够看到,ACTION_DOWN事件沿着黑色箭头方向逐层向内部传递,直到在view的onTouchEvent中消费了该事件,并返回true表示再也不向下传递。随后的事件ACTION_MOVE和ACTION_UP将会沿着绿色箭头传递,直到到达view的onTouchEvent方法。
Case 4 单击view,可是并不在view中处理ACTION_DOWN事件,而是让它传递到ViewGroup中处理。
ACTION_DOWN事件通过ViewGroup,ViewGroup并未拦截而是传递给View。View并未消费该事件而是回传给了ViewGroup,在ViewGroup中消费该事件。
Case 5 单击view,在ViewGroup中拦截ACTION_DOWN事件并消费
ACTION_DOWN事件沿着黑色箭头分发传递,在ViewGroup中对它进行拦截(返回true),因此就再也不继续向view传递ACTION_DOWN事件了。而后在ViewGroup的onTouchEvent方法中消费了该事件,并返回true表示事件已消费。随后的ACTION_MOVE和ACTION_UP事件将沿着绿色箭头传递,直抵最后的消费方法onTouchEvent,而并不通过拦截事件。