当我们触摸了屏幕时,Android 系统捕获到事件,并将事件准确的传递给指定的控件,最后完成相应的反馈,那么这流程是如何完成的,接下来就了解下 Android 的事件传递机制。
先来了解什么是触摸事件,触摸事件就是用户在触摸屏幕后产生的时间。当用户触摸屏幕的时候,通常就会发生 2 - 3 个事件, 手指按下,手指滑动,手指抬起。其中按下和抬起是必然发生的。在 Android 中封装了一个类来保存触摸的相关信息 ---- MotinonEvent。 在这个类里面封装了一些东西,比如触摸点的坐标,触摸事件的类型,通过判断这些依据,我们发生不同的反馈。
但是,举个例子。我们都知道在 VIewGroup 里面可以包含多个 View 或 ViewGroup 。那么在层层嵌套之下,我们的触摸事件如何才能准确的传递到指定的 View 或 ViewGroup 上呢? 这里要用到一个事件拦截的机制。
举个例子,最外层一个 ViewGroup ,中间嵌套一个 ViewGroup ,最里面是一个 View 。
先看事件如何从最外面的 ViewGroup 传递到最里面的 View 。事件的传递会经过 ViewGroup 的 onInterceptTouchEvent 方法,此方法默认返回值为 false 。为 flase 的时候,事件会继续向下一层传递,所以在默认情况下 事件是可以传递到 View 的。但是如果我们在最外层或者中间层的 ViewGroup 的 onInterceptTouchEvent 方法中把返回值设置为 true 那么整个事件就会被上层拦截并进行处理。
前面说的是拦截,再来说处理。事件的处理通常是在 onTouchEvent 中进行,他也有一个返回值,默认是flase ,此时虽然他进行了处理,但是在返回值为flase 的情况下,他的上一层会接着调用 onTouchEvent 进行处理。如果是 true 那么事件处理就到他这里完全结束,不会反馈到上一层。
总结一下,事件的拦截使用 onInterceptTouchEvent 方法,如果你需要控制事件的 View 是在最底层的话那么不需要更改,因为默认返回值是 flase 事件本来就是一直往下传递的,如果你要控制的 View 是在中间,那么就要调用 onInterceptTouchEvent 进行拦截。当拦截到事件后要进行处理,会调用 onTouchEvent 方法进行处理,并且在最后默认返回 flase 传递事件到上一层继续处理,通常会设置为 true 在本 View 中处理后就不用继续上传。