Android 系统的事件分发

129 阅读3分钟

简介

android 事件分发是指将屏幕点击事件分发至View的过程。当我点击屏幕时,会生成一个MotionEvent事件,交由ViewRootImpl进行分发到关联自身的一个控件树中。

主要的分发流程

在一个Acitivty界面中的分发流程

  1. ViewRootImpl会将MotionEvent事件交由关联控件树的根View即DecorView
  2. DecorView会将点击事件回调到Activity中,
  3. Activity会将点击事件交由PhoneWindow分发,
  4. phoneWindow会将点击事件点击事件交由DecorView的父类的DispatchTouchEvent方法进行分发
  5. dispatchTouchEvent方法中会执行拦截,寻找目标子控件,派发事件一系列操作(由于一个屏幕点击事件正常情况下只能有一个View消费,所以目标View消费了Down事件则后续事件都会由此View消费)。
  6. 首先ViewGroup中进行事件是否需要分发给子View的判断,若分发则会通过onInterceptTouchEvent判断是否进行拦截操作,
  7. 第二步进行目标子控件寻找,如果找到则会创建一个TouchTarget
  8. 第三步判断是否存在TouchTarget,若存在则直接分发给目标子控件,若不存在则自己消费,重复6到8步直到时间到达View控件
  9. 当事件到达View时,View会先判断是否存在onTouchListener,若存在则将事件交由listener处理,若不存在则会交由自身的TouchEvent方法
  10. TouchEvent中会进行点击事件或者长按事件的判断,若存在其监听则会交由其处理。
  11. 此流程中只要一处消费了点击事件则此流程中断,若没消费则会逆向调用onTouchEvent方法直到交由Activity的OnTouchEvent方法。

触摸事件的类别

一个触摸事件有多种状态

  1. ACTION_DOWN:当手指按下的时候会产生此事件
  2. ACTION_MOVE:当手指移动时会产生此事件
  3. ACTION_UP:当手指抬起时会产生此事件
  4. ACTION_CANCEL:当手指移除目标View的时候或者父控件拦截了MOVE事件时会产生此事件
  5. ACTION_POINTER_DOWN:此事件会在ViewGroup中存在,当多指触摸时,第二个及以后的手指按下产生的事件
  6. ACTION_POINTER_UP:此事件会在ViewGroup中存在,当多指触摸时,屏幕上最后一个手指之前的手指抬起会触发此事件。

多指触摸的事件分发

MotionEvent中包含当前屏幕触控点的所有信息,他的内部用了一个数组来存储不同的触控id所对应的坐标数值。

当一个View消费了DOWN事件后,ViewGroup会为该View创建一个TouchTarget,其包含了该View的实例以及触控id,此触控ID可以是多个,因此一个View可以接收多个触控点信息。

当ViewGroup接收到一个多点触控的MotionEvent时,其会根据触控点信息分别找到目标View将其拆分为多个MotionEvent然后分别发送至目标View。

参考文档:

Android事件分发机制