Android事件机制(一)从代码演示的角度整理了一下我对Android事件传递的理解;
Android事件机制(二)从源码的角度分析了一下事件传递的流程,描述了一下onTouchEvent返回false(事件没有被消费)的情况;
接下来看一下事件被消费的情况。

事件分发机制针对的其实可以看作是一系列的事件,也就是一个事件序列,由一个ACTION_DOWN开头,中间n个ACTION_MOVE,然后以ACTION_UPACTION_CANCEL结束。
如果给一个控件注册了Touch事件,每次点击它的时候都会触发一系列的ACTION_DOWN、ACTION_MOVE、ACTION_UP等事件。
需要注意的是,如果在执行ACTION_DOWN的时候dispatchTouchEvent返回了false,后面一系列其它的action就不会再得到执行了。

在代码中设置MyView.onTouchEvent返回true

MyView

运行之后打印日志如下:

Log_5

事件分发的原理跟上篇最后分析Log_1的一样,进行事件处理时,当调用到View.onTouchEvent的时候,这个方法返回了true,即MyView消费了这个事件,从而使MyView.dispatchTouchEvent、MyViewGroupB.dispatchTouchEvent、MyViewGroupA.dispatchTouchEvent这三个方法都返回了true,并且在MyViewGroupB和MyViewGroupA中,mFirstTouchTarget被赋值,导致其super.dispatchTouchEvent没有被调用,也就没有打印出MyViewGroupB和MyViewGroupA的onTouchEvent日志。

每次的Touch事件,总是从ACTION_DOWN开始,此时会重置所有状态,这从ViewGroup的源码也可以看出。

ViewGroup.dispatchTouchEvent

ACTION_DOWN开始,当MyView.onTouchEvent返回true之后,在MyViewGroupB和MyViewGroupA中,mFirstTouchTarget被赋值,接着在收到ACTION_MOVE、ACTION_UP的action之后,由于mFirstTouchTarget不为空,所以最后还是调到MyView.onTouchEvent,由于MyView消费了事件,事件处理也就不再传给MyViewGroupB和MyViewGroupA,最后打印出图Log_5的日志,这一轮的Touch事件也就结束了。

稍微对MyView.onTouchEvent改动一下:

MyView.onTouchEvent

此时再看一下打印的日志:

即,在执行ACTION_DOWN的时候,dispatchTouchEvent返回了false,所以后面一系列其它的action就没有再执行。

再对MyViewGroupB.onTouchEventMyView.onTouchEvent改动一下,都返回true,打印的日志如下:

可以看出,事件处理还是到MyView结束的。
可以简单的认为,如果父View和子View同时会对事件进行消费,那么子View的消费优先。

上面的例子都是直接修改MyView.onTouchEvent的返回值。

下面来看一下MyView.onTouchEvent的部分源码:

MyView.onTouchEvent

可以看到,在10288行会对可点击状态进行一个判断,默认返回false,如果是可点击的,就返回true

因为MyView默认是不可点击的,所以在MyView.onTouchEvent的实现中直接调用super.onTouchEvent的话,就进入了View.onTouchEvent,在执行了ACTION_DOWN的逻辑之后,跳过10288行的代码,直接返回false,导致后面其它的action都无法执行了。

如果给MyView设置成可点击状态,那么MyView.onTouchEvent就会返回true,接着就会处理后面的action,当执行到ACTION_UP时,在10323行会调用一个performClick函数,这个函数的代码如下:

performClick

如果设置的OnClickListener不为空,就会去调用它的onClick方法,
那么也就出现了Log_13所示的情况:

Log_13

好了,Android事件机制的学习和记录就到这里了,稍稍总结一下:
1、Android事件分发从ViewGroup传递给View;
2、Android事件处理从View回传给ViewGroup;
3、如果ViewGroup拦截了事件,就不会传递给View;
4、如果View消费了事件,就不会回传给ViewGroup;
5、如果哪个View消费了ACTION_DOWN事件,后续的action会继续分发到这个View;
6、如果哪个View在执行ACTION_DOWN的时候dispatchTouchEvent或者onTouchEvent返回了false,后面一系列其它的action就不会再得到执行。

撒花~

参考:
Android事件分发机制完全解析,带你从源码的角度彻底理解(上)
Android事件分发机制完全解析,带你从源码的角度彻底理解(下)
Android事件分发机制详解
Android群英传-事件拦截机制分析

更多相关文章

  1. android 导出jar包并使用
  2. Android(安卓)Monkey 压力测试 介绍
  3. 源码学习总结《1》Android(安卓)系统启动流程
  4. Android(安卓)IntentService源码分析
  5. Android(安卓)中文 API (100) —— ScrollView
  6. Android读写XML(中)
  7. Android稳定性测试工具Monkey的使用
  8. Android(安卓)JetPack学习笔记之ViewModel
  9. 对“Android输入事件流程中的EventHub分析及源码演示”的补充

随机推荐

  1. Android 中的缓存机制与实现
  2. 十年心得:一个优秀Android开发人员必须注
  3. 2019年Android版本分布(市场占有率、市场
  4. Android线程间的通信
  5. 对于Android DEX文件详细说明
  6. 基于Android Studio的Android第一个软件-
  7. Android Sensor详解(8)sensor hal层分析第
  8. Android[中级教程]第五章 XML解析之PULL
  9. Android通知示例(一)
  10. Android传感器概述(七)