Android 事件分发机制

前言在日常开发过程中,可能会遇到这些问题:滑动冲突、点击事件响应冲突等问题 。那么造成这些问题的根源到底是什么呢?其实这都是Android事件分发导致的,只有掌握了事件分发机制,才能让我们从根源上理解并解决这类问题 。
事件分发对象事件分发过程中,涉及到三种UI对象类型:Activity、ViewGroup、View 及其派生类 。三者之间的关系如下图:

Android 事件分发机制

文章插图
 
发生一次点击事件时,事件会按照Activity->ViewGroup->View的顺序,进行事件传递 。
  • Activity:控制UI页面的生命周期,是事件分发的入口 。
  • ViewGroup:View的特殊子类,是一组View的集合,是Android中所有布局的父类 。
  • View:所有UI组件的基类,常见的Button、TextView等控件都继承自View 。
Android事件分发机制,其实就是Activity、ViewGroup、View三者对触摸点击事件的事件传递过程 。
事件整体分发流程
Android 事件分发机制

文章插图
事件分发流程图
在整个事件分发,并响应事件的过程中,有三个重要的方法:
  • dispatchTouchEvent:分发(传递)点击事件,当点击事件能够传递给当前View时,该方法就会被调用 。
  • onInterceptTouchEvent:判断是否拦截某个事件,该方法仅在ViewGroup中存在 。一般情况下会在ViewGroup的dispatchTouchEvent方法中调用该方法 。
  • onTouchEvent:处理点击事件,在dispatchTouchEvent内部调用 。
Activity事件分发流程Activity中主要涉及以下两个事件方法:
  • boolean dispatchTouchEvent(MotionEvent ev):事件分发
  • boolean onTouchEvent(MotionEvent event):事件消费
在Activity中接受到点击事件,首先会执行dispatchTouchEvent()方法,进行事件分发 。经过window、decorView依次传递后,页面上的 ViewGroup会接收到该事件 。ViewGroup如果消费了该事件,则分发结束(流程在ViewGroup中继续向下分发),未消费则继续调用Activity的onTouchEvent 方法处理事件,流程图如下:
Android 事件分发机制

文章插图
Activity事件分发流程
ViewGroup事件分发流程ViewGroup 涉及到三个事件分发与处理的方法:
  • dispatchTouchEvent(MotionEvent ev):事件分发
  • onIntercepTouchEvent(MotionEvent ev):事件拦截
  • onTouchEvent(MotionEvent ev):事件消费

Android 事件分发机制

文章插图
ViewGroup事件分发流程图
【Android 事件分发机制】ViewGroup通过dispatchTouchEvent()方法接收到事件,然后根据ViewGroup onInterceptTouchEvent()方法的返回值判断:
  • 返回true,则调用ViewGroup的onTouchEvent()方法,如果消费了事件,则事件传递结束,如果不消费事件,则事件传递回Activity并执行Activity的onTouchEvent()方法;
  • 返回false,则将事件传递给子View,由子View继续完成事件向下分发 。
View的事件分发流程View 主要涉及如下两个事件分发与处理的方法:
  • dispatchTouchEvent(MotionEvent ev):事件分发
  • onTouchEvent(MotionEvent ev):事件消费
 
Android 事件分发机制

文章插图
View事件分发流程图
View通过dispatchTouchEvent方法接收到从ViewGroup传递过来的事件后,直接调用 onTouchEvent方法处理事件 。如果没有消费事件,则调用ViewGroup的onTouchEvent方法处理事件,然后继续ViewGroup事件流程;如果消费了该事件,则分发结束 。


推荐阅读