Android开发经验谈Android开发Android技术知识

Android之事件分发基础篇 [ 一 ]

2020-05-12  本文已影响0人  __Y_Q

Android 事件分发之源码分析系列
Android 之事件分发基础篇 [ 一 ]
Android 之 ViewGroup 事件分发深入源码分析 [ 二 ]
Android 之 View 事件分发深入源码分析 [ 三 ]
Android 之 View 事件分发深入源码分析 [ 总结 ]

网上看了很多博客, 也看了一些书籍. 琢磨了很久, 始终感觉无从下手. 但是还是要写出来整理一下, 免得以后忘记, 以下整理来自不同的博客还有书籍.

还是先从基础的理论开始.

1.1 事件分发的对象

事件分发的对象就是 MotionEvent 对象

每当用户触摸屏幕时, 就会产生 Touch 事件. 而系统会将 Touch 中包含的触摸位置,时间等一些信息封装成 MotionEvent 对象.


 
 

1.2 事件的类型

事件的类型分为以下 4 种.

MotionEvent.ACTION_DOWN     按下View(所有事件的开始)
MotionEvent.ACTION_UP       抬起View(与DOWN对应)
MotionEvent.ACTION_MOVE     滑动View
MotionEvent.ACTION_CANCEL   取消事件(非人为原因)

按下, 滑动, 抬起, 取消这几种事件组成了一个事件流. 事件流以按下为开始, 中间可能有若干次滑动, 以抬起或取消作为结束.
(在 Android 对事件分发的处理过程中, 主要是对按下事件做分发, 进而找到能处理按下事件的 View. 对于后续事件(滑动, 抬起), 则直接分发给能处理按下事件的 View.)


 
 

1.3 事件分发的本质

将触摸事件传递到某个具体 View 处理的过程. 也可以理解为 事件的传递过程即为 分发过程.

即当一个 MotionEvent 产生了以后, 系统需要把这个事件传递给一个具体的 View, 而这个过程就是分发过程.


 
 

1.4 事件分发的组件

分发事件的组件, 也称为分发事件者, 包括了 Activity, ViewGroup, View. 它们的关系如下图所示,


关系图
组件 特点 举例
Activity 安卓视图类 如MainActivity
ViewGroup View的容器,可以包含若干View 各种布局类
View UI类组件的基类 如按钮、文本框

可以看出来. Activity 包含了 ViewGroup, 而 ViewGroup 又可以包含多个 View.


 
 

1.5 核心方法

组件 dispatchTouchEvent onTouchEvent onInterceptTouchEvent
Activity 存在 存在 不存在
ViewGroup 存在 存在 存在
View 存在 存在 不存在

从表格中看,dispatchTouchEvent(),onTouchEvent()方法存在于上文的三个组件中. 而onInterceptTouchEvent()为ViewGroup独有.
( ViewGrou 中, 实际上是没有 onTouchEvent() 方法的. 但是因为 ViewGroup 继承自 View. 而 View 拥有 onTouchEvent() 方法, 所以 ViewGroup 对象也是可以调用 onTouchEvent() 方法的. )

 
简单的介绍这三个方法, 后续几篇中会从源码一步一步的对这三个方法进行分析.
 

  1. public boolean dispatchTouchEvent(MotionEvent ev)

用来进行事件分发. 如果事件能够传递给当前 View. 那么此方法一定会被调用.返回结果受当前 View 的 onTouchEvent 和下级 View 的 dispatchTouchEvent 方法的影响. 表示是否消费当前事件.

 

  1. public boolean onInterceptTouchEvent(MotionEvent ev)

在 dispatchTouchEvent 方法内被调用. 用来判断是否拦截某个事件, 如果当前 ViewGroup 拦截了某个事件, 那么在同一个事件序列中, 此方法不会被再次调用, 返回结果表示是否拦截当前事件.

  1. public boolean onTouchEvent(MotionEvent ev)

在 dispatchTouchEvent 方法内被调用. 用来处理事件. 返回结果表示是否消费当前事件. 如果不消费, 则在同一个事件序列中, 当前 View 无法再次接收到事件

这些方法在调用关系中体现了一个类似"递归"的调用过程, 通过 dispatchTouchEvent() 将事件传递下去, 又通过调用 onTouchEvent() 的返回值将事件传递上来. 中间的这一过程可以通过 onInterceptTouchEvent() 方法(针对 ViewGroup) 或者另外负责分发的方法返回 True, 都可以提前终止这一类似"递归"的调用过程. 进而让事件的处理符合我们的预期

上一篇下一篇

猜你喜欢

热点阅读