(一文弄懂!!超详细!!)安卓事件分发机制-程序员宅基地

技术标签: 安卓  移动开发(AndroidStudio)  android  软件工程  

一、安卓事件分发的整个流程

Android 的事件分发流程是一个从顶至底的层级传递过程,涉及 Activity、ViewGroup 和 View。这个流程确保了触摸事件(如屏幕触摸操作)能够被正确地处理和响应。我们将首先概括一下一次事件触发的整个流程,再逐一对其中的细节进行分别介绍:

1. 事件生成:

  • 当用户触摸屏幕时,底层的硬件和操作系统生成一个触摸事件(如 MotionEvent)。

2. InputManager 处理:

  • InputManager 接收这个事件,并确定哪个窗口(通常对应一个 Activity)应该接收这个事件。

3. Activity 分发:

  • 事件首先到达 Activity,通过 Activity 的 dispatchTouchEvent() 方法开始处理。
  • 如果 Activity 没有完全拦截这个事件,它将事件传递给它的根视图(一个 ViewGroup)。

4. ViewGroup 分发:

  • 在 ViewGroup 中,dispatchTouchEvent() 同样被调用。
  • ViewGroup 可以选择拦截这个事件,通过实现 onInterceptTouchEvent() 方法。如果 ViewGroup 拦截了事件(返回 true),则事件不再向下传递,而是交由 ViewGroup 的 onTouchEvent() 方法处理。
  • 如果 ViewGroup 没有拦截(onInterceptTouchEvent() 返回 false),事件将继续传递给它的子视图。

5. 子视图处理:

  • 事件接着被传递到子视图(可能是另一个 ViewGroup 或一个 View)的 dispatchTouchEvent()
  • 这一过程递归进行,直到找到最终的事件接收者。

6. 事件响应:

  • 最终的视图(View)通过它的 onTouchEvent() 方法处理这个事件。
  • 如果这个视图没有处理(onTouchEvent() 返回 false),事件会回溯到它的父 ViewGroup,以此类推,直到找到能处理这个事件的视图。

7. 事件消费:

  • 一旦事件被一个视图的 onTouchEvent() 方法处理并消费(方法返回 true),事件分发流程结束。这个视图成为了该触摸序列(如一次点击或滑动操作)的消费者,后续的事件(如触摸移动或抬起)也会直接分发给这个视图。

这个流程确保了 Android 应用可以灵活处理用户的触摸输入,同时也提供了多个层级对事件进行截获和响应的能力。
接下来我们将分别对InputManager事件对象涉及的方法以及事件类型逐一进行详细讲解。

二、InputManager

InputManager 在 Android 系统中是一个核心的服务组件,负责管理和分发从各种输入设备(如触摸屏、键盘、鼠标等)来的输入事件。Android 的输入系统架构中处于较为底层的位置,它不仅负责将输入事件从硬件传递到应用,还处理了输入事件的多种复杂场景它在,主要功能和特点包括:

1. 事件接收和处理:

  • InputManager 负责从底层的 Linux 内核接收原始的输入事件。这些事件可能来自触摸屏、物理键盘、鼠标、游戏手柄、陀螺仪等多种输入源。
  • 它对这些原始事件进行预处理,如合成、转换或调整事件数据。

2. 事件分发:

  • 经过处理后,InputManager 将这些事件分发到正确的窗口和视图(View)。这个分发过程涉及判断哪个应用或窗口应该接收事件,并将事件传递给它。
  • 在这个过程中,InputManager 会考虑焦点控制、窗口的布局和层级关系等因素。

3. 多点触控和手势识别:

  • InputManager 能够处理复杂的多点触控数据,识别并分发与多点触控相关的手势事件。
  • 它为应用提供了一个相对简化的接口来处理这些高度复杂的输入。

4. 设备管理:

  • InputManager 还负责管理输入设备,提供查询连接的输入设备、它们的能力和状态等功能。

5. 与应用层的交互:

  • 虽然 InputManager 主要在系统层面运作,但它为应用层提供了接口,使得应用可以查询输入设备的信息、注册以接收特定设备的事件等。
  • 例如,游戏应用可能需要查询游戏手柄的状态或注册接收其输入事件。

6. 安全性和权限管理:

  • InputManager 在处理输入事件时,也需要考虑安全性和权限。例如,它需要确保敏感的输入数据(如密码输入)不会被未授权的应用捕获。
    总的来说,InputManager 是 Android 输入系统的核心,它不仅负责将输入事件从硬件传递到应用,还处理了输入事件的多种复杂场景,确保了输入事件的高效和安全处理。

三、三个事件传递对象

在Android中,事件分发机制主要涉及三个层级的对象:Activity、ViewGroup和View。它们的主要区别如下:

1. Activity:

  • Activity是Android应用中的一个重要组件,代表了一个屏幕上的一个单独的窗口。
  • 它不直接参与触摸事件的处理,但是是事件分发的起点。当一个触摸事件发生时,系统首先将事件传递给当前处于活动状态的Activity。
  • Activity通常包含一个或多个ViewGroup和View,负责整个应用界面的布局和显示。

2. ViewGroup:

  • ViewGroup是一个抽象类,继承自View,是所有布局容器的基类,如LinearLayout、RelativeLayout等。
  • 它不仅是View的容器,而且还负责管理其子View(包括其他ViewGroup)的布局和绘制。
  • 在事件分发过程中,ViewGroup有能力决定是否拦截某个事件(通过onInterceptTouchEvent()方法),如果不拦截,事件则会继续向下传递给其子View。

3. View:

  • View是Android中所有用户界面组件的基类,如按钮、文本框等。
  • View是用户交互的基本单元,用于绘制和处理用户的交互事件,如触摸、点击。
  • 在事件分发机制中,View是事件链的最末端,如果事件传递到了View,它将通过onTouchEvent()方法来处理这个事件。

四、涉及的方法

在Android的事件分发过程中,主要涉及以下几个方法:

1. dispatchTouchEvent():

  • 这是事件分发的起始方法。
  • 在Activity、ViewGroup和View中都有这个方法。
  • 它负责将触摸事件(MotionEvent)分发到正确的子View或者自身。
  • 在ViewGroup中,它还会决定是否调用自己的onInterceptTouchEvent()方法来判断是否要拦截事件。

2. onInterceptTouchEvent():

  • 这个方法只存在于ViewGroup中。
  • 它用于决定当前的ViewGroup是否应该拦截触摸事件。
  • 如果这个方法返回true,表示ViewGroup决定拦截并处理这个事件,事件将不会继续向下传递。
  • 如果返回false,事件会继续传递给子View。

3. onTouchEvent():

  • 这个方法存在于Activity、ViewGroup和View中。
  • 它用于处理触摸事件。
  • 如果事件未被拦截且当前View是事件传递链上的最后一层,该事件最终会传递到这里。

4. dispatchKeyEvent():

  • 虽然主要用于键盘事件的分发,但也是事件分发机制的一部分。
  • 它类似于dispatchTouchEvent(),用于分发按键事件。

5. onKeyDown() 和 onKeyUp():

  • 这些方法用于处理按键事件的按下和释放。
  • 它们存在于Activity和View中。

6. onKeyLongPress():

  • 这个方法用于处理长按键事件。
  • 它通常存在于Activity和View中。

五、涉及的事件类型

1. 触摸事件(Touch Events)

  • MotionEvent 是处理触摸事件的主要类。它包含了诸如触摸屏幕的动作类型(如按下、移动、抬起等)、触摸点的位置、压力、时间戳等信息。
  • 触摸事件的动作类型主要包括 ACTION_DOWN(按下)、ACTION_MOVE(移动)、ACTION_UP(抬起)、ACTION_CANCEL(取消)等。

2. 按键事件(Key Events)

  • KeyEvent 用于处理按键事件,比如用户按下或释放手机上的物理按键(如音量键、返回键等)。
  • 主要的动作类型包括 ACTION_DOWN(按键按下)和 ACTION_UP(按键释放),以及 ACTION_MULTIPLE(多个连续的按键动作)。

3. 滚动事件(Scroll Events)

  • 涉及到滚动操作,如列表滚动。这些通常是由触摸事件触发的,但它们有自己的特殊处理逻辑。

4. 长按事件(Long Press Events)

  • 当用户长时间按住屏幕的某个点时触发。虽然这是基于触摸事件的,但通常需要特殊的处理来区分普通的触摸事件。

5. 焦点变化事件(Focus Change Events)

  • 当用户界面中的焦点发生变化时触发,例如从一个文本框移动到另一个文本框。

6. 手势事件(Gesture Events)

  • 如双指缩放、旋转等。这些事件通常是由多个触摸点组合起来的复杂动作。

7. 其他特定于设备的事件

  • 如陀螺仪事件、加速度计事件等,这些通常用于高级的用户界面交互,例如在游戏或增强现实应用中。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Moonsev/article/details/135919109

智能推荐

JWT(Json Web Token)实现无状态登录_无状态token登录-程序员宅基地

文章浏览阅读685次。1.1.什么是有状态?有状态服务,即服务端需要记录每次会话的客户端信息,从而识别客户端身份,根据用户身份进行请求的处理,典型的设计如tomcat中的session。例如登录:用户登录后,我们把登录者的信息保存在服务端session中,并且给用户一个cookie值,记录对应的session。然后下次请求,用户携带cookie值来,我们就能识别到对应session,从而找到用户的信息。缺点是什么?服务端保存大量数据,增加服务端压力 服务端保存用户状态,无法进行水平扩展 客户端请求依赖服务.._无状态token登录

SDUT OJ逆置正整数-程序员宅基地

文章浏览阅读293次。SDUT OnlineJudge#include<iostream>using namespace std;int main(){int a,b,c,d;cin>>a;b=a%10;c=a/10%10;d=a/100%10;int key[3];key[0]=b;key[1]=c;key[2]=d;for(int i = 0;i<3;i++){ if(key[i]!=0) { cout<<key[i.

年终奖盲区_年终奖盲区表-程序员宅基地

文章浏览阅读2.2k次。年终奖采用的平均每月的收入来评定缴税级数的,速算扣除数也按照月份计算出来,但是最终减去的也是一个月的速算扣除数。为什么这么做呢,这样的收的税更多啊,年终也是一个月的收入,凭什么减去12*速算扣除数了?这个霸道(不要脸)的说法,我们只能合理避免的这些跨级的区域了,那具体是那些区域呢?可以参考下面的表格:年终奖一列标红的一对便是盲区的上下线,发放年终奖的数额一定一定要避免这个区域,不然公司多花了钱..._年终奖盲区表

matlab 提取struct结构体中某个字段所有变量的值_matlab读取struct类型数据中的值-程序员宅基地

文章浏览阅读7.5k次,点赞5次,收藏19次。matlab结构体struct字段变量值提取_matlab读取struct类型数据中的值

Android fragment的用法_android reader fragment-程序员宅基地

文章浏览阅读4.8k次。1,什么情况下使用fragment通常用来作为一个activity的用户界面的一部分例如, 一个新闻应用可以在屏幕左侧使用一个fragment来展示一个文章的列表,然后在屏幕右侧使用另一个fragment来展示一篇文章 – 2个fragment并排显示在相同的一个activity中,并且每一个fragment拥有它自己的一套生命周期回调方法,并且处理它们自己的用户输_android reader fragment

FFT of waveIn audio signals-程序员宅基地

文章浏览阅读2.8k次。FFT of waveIn audio signalsBy Aqiruse An article on using the Fast Fourier Transform on audio signals. IntroductionThe Fast Fourier Transform (FFT) allows users to view the spectrum content of _fft of wavein audio signals

随便推点

Awesome Mac:收集的非常全面好用的Mac应用程序、软件以及工具_awesomemac-程序员宅基地

文章浏览阅读5.9k次。https://jaywcjlove.github.io/awesome-mac/ 这个仓库主要是收集非常好用的Mac应用程序、软件以及工具,主要面向开发者和设计师。有这个想法是因为我最近发了一篇较为火爆的涨粉儿微信公众号文章《工具武装的前端开发工程师》,于是建了这么一个仓库,持续更新作为补充,搜集更多好用的软件工具。请Star、Pull Request或者使劲搓它 issu_awesomemac

java前端技术---jquery基础详解_简介java中jquery技术-程序员宅基地

文章浏览阅读616次。一.jquery简介 jQuery是一个快速的,简洁的javaScript库,使用户能更方便地处理HTML documents、events、实现动画效果,并且方便地为网站提供AJAX交互 jQuery 的功能概括1、html 的元素选取2、html的元素操作3、html dom遍历和修改4、js特效和动画效果5、css操作6、html事件操作7、ajax_简介java中jquery技术

Ant Design Table换滚动条的样式_ant design ::-webkit-scrollbar-corner-程序员宅基地

文章浏览阅读1.6w次,点赞5次,收藏19次。我修改的是表格的固定列滚动而产生的滚动条引用Table的组件的css文件中加入下面的样式:.ant-table-body{ &amp;amp;::-webkit-scrollbar { height: 5px; } &amp;amp;::-webkit-scrollbar-thumb { border-radius: 5px; -webkit-box..._ant design ::-webkit-scrollbar-corner

javaWeb毕设分享 健身俱乐部会员管理系统【源码+论文】-程序员宅基地

文章浏览阅读269次。基于JSP的健身俱乐部会员管理系统项目分享:见文末!

论文开题报告怎么写?_开题报告研究难点-程序员宅基地

文章浏览阅读1.8k次,点赞2次,收藏15次。同学们,是不是又到了一年一度写开题报告的时候呀?是不是还在为不知道论文的开题报告怎么写而苦恼?Take it easy!我带着倾尽我所有开题报告写作经验总结出来的最强保姆级开题报告解说来啦,一定让你脱胎换骨,顺利拿下开题报告这个高塔,你确定还不赶快点赞收藏学起来吗?_开题报告研究难点

原生JS 与 VUE获取父级、子级、兄弟节点的方法 及一些DOM对象的获取_获取子节点的路径 vue-程序员宅基地

文章浏览阅读6k次,点赞4次,收藏17次。原生先获取对象var a = document.getElementById("dom");vue先添加ref <div class="" ref="divBox">获取对象let a = this.$refs.divBox获取父、子、兄弟节点方法var b = a.childNodes; 获取a的全部子节点 var c = a.parentNode; 获取a的父节点var d = a.nextSbiling; 获取a的下一个兄弟节点 var e = a.previ_获取子节点的路径 vue

推荐文章

热门文章

相关标签