当前位置: 首页 > news >正文

View触摸反馈与事件分发原理

View的触摸反馈用于定义View对各类点击事件的响应方式。是进行自定义View的核心环节。本文详细介绍事件达到View后的事件拦截模型、分发流程,以及View原生事件处理方式。帮助大家更好的理解和掌握Android事件的原理和进行自定义view实践。

1、事件分发模型

我们以一个简单的View结构:一个ViewGroup和两个有交叠的子View,来看一下事件分发的典型模型。

用户点击屏幕后,事件会被InputManager捕捉到,然后传递给Window,再通过Window传递到DecorView。然后再一级一级,从上到下传下来。这个过程不在这里详细介绍。读者可以从我的另一篇文章“从子线程更新UI异常问题看View加载绘制流程”了解一下view和window的关系。

这里我们直接从事件到达View开始讲起。事件到达View首先是会到达View树上最顶层的布局,如上面图的“父View”,它是一个容器。

先调用父View的dispatchTouchEvent方法,然后onInterceptTouchEvent()方法判断是否进行拦截。如果不拦截,则走图上黑色箭头的路线。事件首先到达点击范围内屏幕最上层的子View,如果子View将事件消费,则事件到此结束,此次事件将由该View处理;如果子View不消费,则传递到它下层的子View,继续做同样的判断,如果所有子view都不消费。最后由父View处理。

如果开始时父view的onInterceptTouchEvent()方法拦截事件,则事件不会再向子View分发,直接由父View处理。如上图的红色箭头流程。

以上就是典型的事件分发的模型,如果多层父View和多个子View,只要递归的看就可以了。如果涉及到事件的拦截,要复杂一些,我们后面再看。

2、事件序列

Android的触摸事件,主要有ACTION_DOWN(手指按下)、ACTION_MOVE (手指移动)、ACTION_UP(手指抬起)。其他还有ACTION_POINT_DOWN (非第一根手指按下)、ACTION_POINT_UP(非第一根手指抬起)、ACTION_CANCEL(事件取消)等。

实际上事件的产生都是伴随着一个完整的过程,是一个事件序列。它是从DOWN(触摸)事件开始,中间经历一系列的MOVE(滑动)事件,最后以UP或CANCEL事件结束(手指抬起)。

我们在讨论事件分发、拦截、处理时,考虑的都是一个完整的事件序列。

3、事件拦截与分发

我们已经知道事件分发的基本模型。本章节将详细看一下事件分发与拦截流程。主要是在ViewGroup的dispatchTouchEvent()方法中进行。接下来我们详细分析该源码。请读者在阅读时,时刻回忆上一章节的事件分发的模型。

ACTION_DOWN除了表示一个手指按下事件,还表示这是一个新的事件序列的开始。因此先对之前的标志、状态进行清空初始化。

3.1 拦截的判断

intercepted就是是否要进行拦截的判断,可以理解为接下来是否要进行事件分发。事件分发就是通过一定方法,在view树中找到最合适处理该事件的控件的过程,详细内容在“事件分发”中进行介绍。

intercepted为true,表示进行拦截,不走分发流程,直接走事件处理。如果intercepted为false,表示需要进行事件分发,分发完成后再进行事件处理。

“mFirstTouchTarget != null”, 表示此时有子view在处理此次事件序列。如果是事件序列开始或者有子view在处理事件时,进行进一步判断。否则,设置intercepted为true,走事件处理流程。

接下来判断,如果子view设置了不允许拦截,则intercepted为false,进行事件分发。如果子view未设置,则通过onInterceptTouchEvent方法判断父view是否拦截,这种方式叫做外部拦截

“FLAG

http://www.jsqmd.com/news/1121040/

相关文章:

  • 电液伺服系统ADRC控制方案设计与Simulink实现
  • 时空编码超表面在射频计算中的创新应用
  • vue 延迟加载
  • Debian(WSL)安装gprMax教程 - 适用于Windows系统
  • mtgsig 1.2逆向分析:从混淆代码到本地化实现
  • .net6 中 WebAPI 发布后Swagger不显示
  • 野数据处理实战:构建五层韧性物联网数据流水线
  • Gemini 3.1 Pro国内可用的四种实测路径与选型指南
  • 2、<入门>编程求解下列式子的值:S=1+2+3+...+n
  • Java对称加密实战:从AES/DES原理到安全实现与避坑指南
  • CAPL脚本函数不能返回数组的替代方案
  • go:Timing Functions Pattern
  • 三步搞定跨语言障碍:STranslate翻译工具完全指南
  • 融云获 2022 中国技术先锋年度评选「中国技术品牌影响力企业」奖
  • AI开发工程化规范与实践指南
  • 关于const、指针和引用【C++复习】
  • Micro Journal开源硬件设计:3D打印外壳与PCB制作教程
  • 神经网络激活函数实战指南:从原理到工程选型
  • BetterJoy终极指南:让Switch手柄在PC上焕发新生
  • RTX A5000与PIC18LF45K42构建安全云连接方案
  • Springboot整合MybatisPlus【一】
  • 毕业生必备7款AI写作辅助平台,一站式搞定选题初稿与降重
  • 赞赞赞!融云收获行业媒体「组团打 Call」
  • 3分钟掌握npx skills:AI技能管理工具的革命性体验
  • Git最新教程通俗易懂----狂神说Java -- ---学习笔记
  • Elm-platform项目管理指南:使用elm-package管理依赖和发布包
  • Spectre性能调优技巧:从CPU到CUDA的完整优化路线图
  • Android WebView安全防护:从HTTPS到JS交互的全面防御方案
  • hexo成功后localhost拒绝连接
  • Scarab:让空洞骑士模组管理变得直观简单的跨平台解决方案