<返回更多

Android 事件分发机制

2022-08-01    前端Vs过客
加入收藏

前言

在日常开发过程中,可能会遇到这些问题:滑动冲突、点击事件响应冲突等问题。那么造成这些问题的根源到底是什么呢?其实这都是Android事件分发导致的,只有掌握了事件分发机制,才能让我们从根源上理解并解决这类问题。

事件分发对象

事件分发过程中,涉及到三种UI对象类型:Activity、ViewGroup、View 及其派生类。三者之间的关系如下图:

 

发生一次点击事件时,事件会按照Activity->ViewGroup->View的顺序,进行事件传递。

Android事件分发机制,其实就是Activity、ViewGroup、View三者对触摸点击事件的事件传递过程。

事件整体分发流程

事件分发流程图

在整个事件分发,并响应事件的过程中,有三个重要的方法:

Activity事件分发流程

Activity中主要涉及以下两个事件方法:

在Activity中接受到点击事件,首先会执行dispatchTouchEvent()方法,进行事件分发。经过window、decorView依次传递后,页面上的 ViewGroup会接收到该事件。ViewGroup如果消费了该事件,则分发结束(流程在ViewGroup中继续向下分发),未消费则继续调用Activity的onTouchEvent 方法处理事件,流程图如下:

Activity事件分发流程

ViewGroup事件分发流程

ViewGroup 涉及到三个事件分发与处理的方法:

ViewGroup事件分发流程图

ViewGroup通过dispatchTouchEvent()方法接收到事件,然后根据ViewGroup onInterceptTouchEvent()方法的返回值判断:

View的事件分发流程

View 主要涉及如下两个事件分发与处理的方法:

 

View事件分发流程图

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

注意:

在View把事件消费后,如果View的onTouch方法返回true,View的dispatchTouchEvent方法会直接返回true,不会再调用View的onClick方法;只有当onTouch方法返回false时,才会有onClick事件处理。

思考点

这两个方法都是在View的dispatchTouchEvent中调用,但onTouch优先于onTouchEvent执行。如果在onTouch方法中返回true将事件消费掉,onTouchEvent()将不会再执行。

特别注意:请看下面代码

//1. mOnTouchListener的值不能为空 
//2. 当前点击的控件必须是enable的
mOnTouchListener !=null && (mViewFlags & ENABLED_MASK) == ENABLED &&mOnTouchListener.onTouch(this, event)

因此如果你有一个控件是非enable的,那么给它注册onTouch事件将永远得不到执行。对于这一类控件,如果我们想要监听它的touch事件,就必须通过在该控件中重写onTouchEvent方法来实现。

接收了ACTION_DOWN事件的函数不一定能收到后续事件(ACTION_MOVE、ACTION_UP);如果在某个对象(Activity、ViewGroup、View)的dispatchTouchEvent()消费事件(返回true),那么收到ACTION_DOWN的函数也能收到ACTION_MOVE和ACTION_UP。

声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多资讯 >>>