Android开发之事件分发

#来自ウルトラマンゼロ(哉阿斯)

1 Activity 构成

平常布局展示在ContentView中。

2 事件分发

事件分发的本质其实就是把事件(Touch)封装成 MotionEvent 类,然后传递给 View 的层级处理。

MotionEvent 事件类型主要有下面四种:

MotionEvent.ACTION_DOWN按下事件(事件开始)
MotionEvent.ACTION_UP抬起事件(与 DOWN 对应)
MotionEvent.ACTION_MOVE移动事件
MotionEvent.ACTION_CANCEL结束事件

事件分发由三个方法协作完成:

  • dispatchTouchEvent():事件分发
  • onTouchEvent():消费事件、在 dispatchTouchEvent() 中调用
  • onInterceptTouchEvent():拦截事件、只有 ViewGroup 有、在 dispatchTouchEvent() 中调用

3 dispatchTouchEvent()

主要是负责分发,是安卓事件分发过程中的核心。

  • 返回 TRUE,则表明对事件已经处理,不用继续调用其余组件的分发方法,即停止分发
  • 返回 FALSE,则表明对事件不能处理,需要按照规则继续分发事件,在不复写该方法的情况下,除了一些特殊的组件,其余组件都是默认返回 False。

3.1 Activity#dispatchTouchEvent()

可以用以下伪代码说明:

public boolean dispatchTouchEvent(MotionEvent ev) {if (child.dispatchTouchEvent(ev)) {return true;//子 View 消费事件,返回 TRUE,让调用者知道该事件已被消费} else {return onTouchEvent(ev);//子 View 没有消费事件,调用自身的 onTouchEvent}
}
  • 事件经过传递后,事件被消费了(返回 TRUE),则 Activity 的分发方法也返回 TRUE,表示该事件已经被消费了。
  • 事件经过传递后,事件没有被消费(返回 FALSE),则 Activity 调用 onTouchEvent() 去处理。
  • onTouchEvent 消费事件,返回 TRUE(表示已消费事件),并作为 dispatchTouchEvent() 的返回值,让调用它的对象知道 Activity 消费事件。
  • onTouchEvent 没有消费事件,返回 FALSE(表示未消费事件),并作为 dispatchTouchEvent() 的返回值。让调用它的对象知道该 Activity 没有消费事件,需要继续处理。

3.2 ViewGroup#dispatchTouchEvent()

public boolean dispatchTouchEvent(MotionEvent ev) {if (!onInterceptTouchEvent(ev)) {return child.dispatchTouchEvent(ev);//不拦截,则传给子 View 进行分发处理} else {return onTouchEvent(ev);//拦截事件,交由自身 onTouchEvent 方法处理}
}
  • 返回 FALSE(不拦截),则交给子 View 去调用 dispatchTouchEvent() 方法
  • 返回 TRUE(拦截),则调用 ViewGroup 对象 onTouchEvent(ev) 方法处理。

3.3 View#dispatchTouchEvent()

public boolean dispatchTouchEvent(MotionEvent ev) {//listener 不为空,调用 onTouch方法if (mOnTouchListener != null && mOnTouchListener.onTouch(this, event)) {return true;//若onTouch方法返回TRUE,消费事件,则 dispachtouTouchEvent返回 TRUE,让其调用者知道该事件已被消费,可见 setOnTouchListener 优先级比较高。}return onTouchEvent(ev);//没有消费事件,则调用对象自身的 onTouchEvent() 处理。
}
  • onTouch() 返回 TRUE,则 dispatchTouchEvent 也会返回TRUE,表示消费该事件。
  • onTouch() 返回 FALSE,或者 mOnTouchListener 为空,调用自身的 onTouchEvent() 处理,是否消费事件,可以由其返回值判断。

4 onInterceptTouchEvent

该方法是 ViewGroup 独有的,对事件进行提前拦截。一般情况下,该方法是默认返回 FALSE,表示不拦截。 如果自定义 ViewGroup 希望拦截事件,不希望事件传递,可以覆写该方法,返回 TRUE,即可阻止向下的传播过程。

子 View 也可以通过 requestDisallowInterceptTouchEvent 来设置 FLAG_DISALLOW_INTERCEPT 标志位,禁止 ViewGroup 拦截除了 DOWN 之外的事件。

  • 返回 TRUE,则会将事件拦截,自身的 onTouchEvent 处理。

  • 返回 FALSE,则继续传递给子 View 执行分发流程。

5 onTouchEvent

对事件进行处理。

  • 返回 TRUE 表示已经处理了事件,
  • 返回 FALSE 表示没有对事件进行处理,需要继续传递事件。一般情况下,默认为 FALSE。在 View 的onTouchEvent 方法中,如果设置了 setOnClickListenter、setOnLongClickListene 处理,返回 TRUE。

6 总结

  • 当事件产生之后,传递顺序:Activity -> PhoneWindow -> 顶层 ViewGroup
  • 事件传递中一般考虑 ViewGroup 的 onInterceptTouchEvent(),一般情况下我们不会重写 dispatchTouchEvent()。
  • 对于根 ViewGroup,事件首先传递到 dispatchTouchEvent():
    • onInterceptTouchEvent() -> TRUE,则表示拦截事件,这个事件就由 onTouchEvent()
    • onInterceptTouchEvent() -> FALSE,则表示不拦截事件,这个事件会交给它的子 View dispatchTouchEvent()
    • 如果事件传递到底层的 View,View 是没有子View的,就会调用 View 的 dispatchTouchEvent(),通常情况下,会调用 View 的 onTouchEvent() 处理事件。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/392812.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RAG与Fine Tuning:如何选择正确的方法

今日份知识你摄入了么? 生成式人工智能有潜力改变你的业务和数据工程团队,但前提是要正确实施。那么,你的数据团队如何才能真正利用大型语言模型或生成式人工智能_(GenAI)_计划来驱动价值呢? 领先的组织通…

我在高职教STM32——I2C通信入门(1)

大家好,我是老耿,高职青椒一枚,一直从事单片机、嵌入式、物联网等课程的教学。对于高职的学生层次,同行应该都懂的,老师在课堂上教学几乎是没什么成就感的。正是如此,才有了借助CSDN平台寻求认同感和成就感的想法。在这里,我准备陆续把自己花了很多心思设计的教学课件分…

Sentinel-1 Level 1数据处理的详细算法定义(五)

《Sentinel-1 Level 1数据处理的详细算法定义》文档定义和描述了Sentinel-1实现的Level 1处理算法和方程,以便生成Level 1产品。这些算法适用于Sentinel-1的Stripmap、Interferometric Wide-swath (IW)、Extra-wide-swath (EW)和Wave模式。 今天介绍的内容如下: Sentinel-1 L…

Python爬虫新手指南及简单实战

网络爬虫是自动化获取网络信息的高效工具,Python因其强大的库支持和简洁的语法成为编写网络爬虫的首选语言。本教程将通过一个具体的案例(基于Microsoft Edge浏览器的简单爬取),指导你使用Python实现一个完整的网络爬虫&#xff0…

NIO专题学习(一)

一、BIO/NIO/AIO介绍 1. 背景说明 在Java的软件设计开发中,通信架构是不可避免的。我们在进行不同系统或者不同进程之间的数据交互,或者在高并发的通信场景下都需要用到网络通信相关的技术。 对于一些经验丰富的程序员来说,Java早期的网络…

PXE 服务器搭建——启动界面设计实验

环境准备: 前期准备: 解决 kickstart 实验出现的 DHCP 的问题-CSDN博客 http://t.csdnimg.cn/5vZP0 当前准备: 两台虚拟机:RHEL7 OpenEuler(作为测试机器使用) ip:172.25.254.100 yum install syslinux.x…

【Web开发手礼】探索Web开发的秘密(十五)-Vue2(2)AJAX、前后端分离、前端工程化

主要介绍了AJAX、前后端分离所需的YApi、前端工程化所需要的环境安装!!! 目录 前言 AJAX ​原生Ajax Axios Axios入门 案例 前后端分离开发 YApi ​前端工程化 环境准备 总结 前言 主要介绍了AJAX、前后端分离所需的YApi、前端工…

2024华数杯c题题解(一)

目录 原题背景 背景分析 问题一 思路 代码 问题二 思路 代码 原题背景 最近,“city 不 city”这一网络流行语在外国网红的推动下备受关注。随着我国过境免签政策的落实,越来越多外国游客来到中国,通过网络平台展示他们在华旅行的见闻…

出现 No mapping for DELETE/GET等

出现 No mapping for DELETE/GET等 错误一:请求url不对 修改前 如下图可知后端请求url为http://localhost:8080/user/addressBook 运行后控制台出现 发现后端请求url比前端请求url少了/ 改正: 在DeleteMapping后面加上 / DeleteMapping("/&quo…

mysql操作(进阶)

1.数据库约束 数据库自动对数据的合法性进行校验检查的一系列机制,目的是为了保证数据库中能够避免被插入或者修改一些非法数据。 (1)mysql中提供了以下的约束: a.NOT NULL:指定某列不能为null b.UNIQUE&#xff1…

搭建pxe网络安装环境实现服务器自动部署

目录 配置 kickstart自动安装脚本 搭建dhcp服务 搭建pxe网络安装环境实现服务器自动部署 测试 配置 kickstart自动安装脚本 yum install system-config-kickstart #在rhel7做,rhel9要收费 system-config-kickstart #启动图形制作工具 vim …

工具收集 - tinytask(相当于迷你的按键精灵)

工具收集 - tinytask(相当于迷你的按键精灵) 简介首页 简介 TinyTask 是一款极简主义的 PC 自动化应用程序,您可以用它来记录和重复操作。顾名思义,它小得令人难以置信(仅 36KB!),极…

C++第三十一弹---C++继承机制深度剖析(下)

✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】【C详解】 1.菱形继承及菱形虚拟继承 1.1 单继承 单继承:一个子类只有一个直接父类时称这个继承关系为单继承。 Student的直接父类是Person&#xff…

openai command not found (mac)

题意:mac 系统上无法识别 openai 的命令 问题背景: Im trying to follow the fine tuning guide for Openai here. 我正在尝试遵循 OpenAI 的微调指南 I ran: 我运行以下命令 pip install --upgrade openaiWhich install without any errors.…

干货!如何选择Ai大模型(LLMs)?

过去一年里,大型语言模型(LLMs)在人工智能界风起云涌,纷纷以突破性的进步拓展生成式人工智能的可能性。新模型层出不穷,令人目不暇接。 这些模型依靠日益增长的参数数量和庞大的数据集进行训练,显著提升了…

redis的key莫名失踪?

背景 在线上环境下,发现redis中key被莫名奇妙的删除了,起初怀疑是key过期但是查询了TTL并没有,在日志上加了删除key操作的打印 但是并没有看到产出这个key的日志记录,而且每次都是这个key被莫名奇妙删除掉,感觉很诡异。…

blender里的辉光

cycle的辉光, 点开支持后期效果 eevee的辉光,直接点bloom就行。 eevee的透明

sqli-labs-master初学者题目练习

Less-1 从源码可以看出id为注入点,且为单引号过滤 使用 闭合 --为注释 原本应该用--‘space’,但-与‘连在一起无法起到注释作用 order by为联合查询——同时查询两张表,但两张表列数必须相同 所有从以上两张图可以看出此表格有三列数据 爆…

防火墙工具iptables应用详解

文章目录 前言一、Netfilter内核二、Netfilter与iptables的关系三、iptables的表与链四、iptables的常用命令与参数五、 iptables使用案例 前言 iptables是Linux系统中一款强大的防火墙工具,它基于Netfilter内核模块,允许管理员定义数据包的转发、过滤和…

了解MVCC

概念 MVCC,全称Multi-Version Concurrency Control,即多版本并发控制,是一种并发控制的方法,维护一个数据的多个版本,使得读写操作没有冲突,快照读为MySQL实现MVCC提供了一个非阻塞读功能。MVCC的具体实现…