Android6.0触摸事件分发机制解读

学向勤中得,萤窗万卷书。这篇文章主要讲述Android6.0触摸事件分发机制解读相关的知识,希望能为你提供帮助。
本篇博文是android触摸事件分发机制系列博文的第一篇, 带领大家从全局掌握Android触摸事件分发机制。特别声明的是, 本源码解读是基于最新的Android6.0版本。
( 一) Android6.0源码解读之View点击事件分发机制
( 二) Android6.0源码解读之ViewGroup点击事件分发机制
( 三) Android6.0源码解读之Activity点击事件分发机制
为什么要解读触摸事件分发机制 1.掌握View事件分发机制
2.为解决View滑动冲突提供理论支持
3.了解Android最新源码改动
Touch触摸事件 在Android中Touch触摸事件主要包括点击( onClick) 、长按( onLongClick) 、拖拽( onDrag) 、滑动( onScroll) 等, 点击又包括单击和双击, 另外还包括单指操作和多指操作。其中Touch的第一个状态是 ACTION_DOWN, 表示按下了屏幕后, touch将会有后续事件, 比如移动、抬起等, 一个Action_DOWN, 一个ACTION_UP, 许多个ACTION_MOVE, 就构成了Android中众多的事件。所有的操作事件首先必须执行的是按下操作( ACTIONDOWN) , 之后所有的操作都是以此作为前提, 当按下操作完成后, 接下来可能是一段移动( ACTIONMOVE) 然后抬起( ACTION_UP) , 或者是按下操作执行完成后没有移动就直接抬起。

● 按下( ACTION_DOWN)
● 移动( ACTION_MOVE)
● 抬起( ACTION_UP)
● 取消手势( ACTION_CANCEL)
● 滑出屏幕( ACTION_OUTSIDE)
Android中的Touch事件都是从ACTION_DOWN开始的:
单指操作: ACTION_DOWN---ACTION_MOVE----ACTION_UP 多指操作: ACTION_DOWN---ACTION_POINTER_DOWN---ACTION_MOVE--ACTION_POINTER_UP---ACTION_UP.

触摸事件分发机制涉及的三个重要方法
public boolean dispatchTouchEvent(MotionEvent ev)

dispatchTouchEvent用来进行事件的分发。如果事件能够传递给当前的View, 那么此方法一定会被调用, 返回结果受当前View的onTouchEvent和下级View的dispatchTouchEvent方法的影响, 表示是否消耗当前事件。
public boolean onInterceptTouchEvent(MotionEvent event)

onInterceptTouchEvent是ViewGroup提供的方法, 用来判断是否拦截某个事件, 如果当前View拦截了某个事件, 那么在同一个事件序列当中, 此方法不会被再次调用, 返回结果表示是否拦截当前事件。默认返回false, 返回true表示拦截。
public boolean onTouchEvent(MotionEvent event)

onTouchEvent在dispatchTouchEvent方法中调用, 用来处理点击事件, 返回结果表示是否消耗当前的事件, 如果不消耗, 则在同一个事件序列中, 当前View无法再次接受到事件。view中默认返回true, 表示消费了这个事件。
这三个重要方法的分布情况 在View中包含以下两个方法:
public boolean dispatchTouchEvent(MotionEvent ev);
public boolean onTouchEvent(MotionEvent ev);
在ViewGroup中包含以下三个方法:
public boolean dispatchTouchEvent(MotionEvent ev);
public boolean onInterceptTouchEvent(MotionEvent ev);
public boolean onTouchEvent(MotionEvent ev);
在Activity中包含以下两个方法:
public boolean dispatchTouchEvent(MotionEvent ev);
public boolean onTouchEvent(MotionEvent ev);
Android6.0触摸事件分发机制解读

文章图片

Android触摸事件分发流程图
Android6.0触摸事件分发机制解读

文章图片

Android触摸事件流程总结
1.一个事件序列是指从手指触摸屏幕开始, 到手指离开屏幕结束, 这个过程中产生的一系列事件。同一个事件序列是以ACTION_DOWN事件开始, 中间含有数量不定的MOVE事件, 最终以ACTION_UP事件结束。
2.事件传递的顺序是: Activity-> Window-> View, 即事件总是先传递给Activity, 然后在传递给Window, 最后在传递给View, 顶级View接收到事件后, 就会按照事件分发机制去分发事件。
3.事件的传递过程是由外向内的, 即事件总是由父元素分发给子元素。
4.正常情况下, 一个事件序列只能被一个View拦截且消耗。一旦一个元素拦截了某次事件, 那么同一个事件序列内的所有事件都会直接交给它处理, 因此同一个事件序列中的事件不能分别由两个View同时处理, 但是通过特殊手段可以做到, 比如一个View将本该自己处理的事件通过onTouchEvent强行传递给其他View处理。
5.某个View一旦开始处理事件, 如果它不消耗ACTION_DOWN事件, 那么同一事件序列的其他事情都不会再交给它来处理, 并且事件将重新交给它的父容器去处理( 调用父容器的onTouchEvent方法) ; 如果它消耗ACTION_DOWN事件, 但是不消耗其他类型事件, 那么这个点击事件会消失, 父容器的onTouchEvent方法不会被调用, 当前view依然可以收到后续的事件, 但是这些事件最后都会传递给Activity处理。
6.Android点击事件分发是到达顶级View后( 一般是ViewGroup) , 会调用ViewGroup的dispatchTouchEvent方法, 其中它的onInterceptTouchEvent方法如果返回true, 则会对事件传递进行拦截, 事件由ViewGroup处理; 如果onInterceptTouchEvent方法返回false, 则代表不对事件进行拦截, 默认返回false。则此时子View中的dispatchTouchEvent方法将被调用, 到此, 事件已经由顶级View传递给了下一层的View, 接下来的过程是一个递归循环的过程, 和顶级View事件分发过程是一致的, 直到完成整个事件分发。
针对View、ViewGroup、Activity中的事件分发机制源码解读
各位童鞋可以参考下面链接进行系统学习
( 一) Android6.0源码解读之View点击事件分发机制
( 二) Android6.0源码解读之ViewGroup点击事件分发机制
【Android6.0触摸事件分发机制解读】( 三) Android6.0源码解读之Activity点击事件分发机制

    推荐阅读