【Android View】事件分发的过程

Android输入事件从读取到分发四:InputDispatcherThread发送事件到View结构树的过程 通过上一节的分析,我们发现InputDispatcherThread使用InputChannel的sendMessage方法发送了一条消息,但是我们不知道谁在接收这条消息。因此,这一节我们的目标很明确,弄懂”是谁在接收消息,然后这条消息是怎么分发到View的结构树中的”。 上一节我们说InputChannel的本质是linux本地套接字,因为它内部使用socketpair()函数创建了一对套接字描 阅读详情

前言

Android View 虽然不是四大组件,但其并不比四大组件的地位低。而View的核心知识点事件分发机制则是Android开发过程中一个重点也是难点。ScrollView嵌套RecyclerView(或者ListView)的滑动冲突这种问题的理论基础就是事件分发机制。

Android中的事件分发机制也就是View与ViewGroup的对事件的分发与处理。在ViewGroup的内部包含了许多View,而ViewGroup继承自View,所以ViewGroup本身也是一个View。对于事件可以通过ViewGroup下发到它的子View并交由子View进行处理,而ViewGroup本身也能够对事件做出处理。

什么是事件?什么是事件序列?

我们对屏幕的点击,滑动,抬起等一系的动作都是由一个一个MotionEvent对象组成的。根据不同动作,主要有以下三种事件类型:
1.ACTION_DOWN:手指刚接触屏幕,按下去的那一瞬间产生该事件
2.ACTION_MOVE:手指在屏幕上移动时候产生该事件
3.ACTION_UP:手指从屏幕上松开的瞬间产生该事件

上面提到了三种事件ACTION_DOWN、ACTION_MOVE和ACTION_UP。它们都是单独的事件,而事件序列由它们组成。一个事件序列指的是:由一个ACTION_DOWN事件,0个或者1个或者多个ACTION_MOVE事件,加上一个ACTION_UP事件组成的一个序列。

事件是用户与屏幕发生交互时产生的,而Activity则是Android中负责与用户发生交互的组件。所以事件的传递,首先是到达Activity,再通过内部传递之后,到达我们的布局文件中的layout和View。事件发生之后,需要进行响应处理,再传递的过程中,由上往下,都有可能有机会处理一个事件序列。如果从Activity往下,到最终的View,事件都没有得到处理,则事件又从下往上,回到Activity,如果回到Activity之后,Activity没有处理这个事件,那么这个事件就会自动结束。

下面简单看下三个事件方法:

mButton.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        e("MotionEvent: ACTION_DOWN");
                        break;
                    case MotionEvent.ACTION_MOVE:
                        e("MotionEvent: ACTION_MOVE");
                        break;
                    case MotionEvent.ACTION_UP:
                        e("MotionEvent: ACTION_UP");
                        break;
                }
                return false;
            }
        }); 

定义一个按钮,设置触摸事件,根据手指的触发,执行不同的类型是事件。

事件分发的三个方法:

dispatchTouchEvent:用于分发传递事件,只要事件能够传递到当前View,这个方法就会被调用。

onInterceptTouchEvent:用于判断是否拦截事件,不往下传递。(此方法只有ViewGroup拥有,Activity和View没有)此方法在dispatchTouchEvent方法中调用。

onTouchEvent:用于处理事件,同样也是在dispatchTouchEvent方法中调用。

ViewGroup的事件分发方法:

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    show("dispatchTouchEvent",ev);
    //switch
    return super.dispatchTouchEvent(ev);
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    show("onInterceptTouchEvent",ev);
    //switch
    return super.onInterceptTouchEvent(ev);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    show("onTouchEvent",event);
    return super.onTouchEvent(event);
} 

View的事件分发方法:

@Override
public boolean dispatchTouchEvent(MotionEvent event) {
    show("dispatchTouchEvent",event);
    //switch
    return super.dispatchTouchEvent(event);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    show("onTouchEvent",event);
    //switch
    return super.onTouchEvent(event);
} 

View是最后的事件处理,所以没有拦截事件。

dispatchTouchEvent

public boolean dispatchTouchEvent(MotionEvent ev)

1)return true: 表示消耗了当前事件,有可能是当前 View 的 onTouchEvent 或者是子 View 的 dispatchTouchEvent消费了,事件终止,不再传递。

2)return false: 调用父 ViewGroup 或 Activity 的 onTouchEvent。 (不再往下传)。

3)return super.dispatherTouchEvent: 则继续往下(子 View )传递,或者是调用当前 View 的 onTouchEvent 方法;

总结: 用来分发事件,即事件序列的大门,如果事件传递到当前 View 的 onTouchEvent或者是子 View 的 dispatchTouchEvent,即该方法被调用了。 另外如果不消耗 ACTION_DOWN 事件,那么 down, move, up 事件都与该 View 无关,交由父类处理(父类的 onTouchEvent 方法)

onInterceptTouchEvent

public boolean onInterceptTouchEvent(MotionEvent ev)

1)return true: ViewGroup 将该事件拦截,交给自己的 onTouchEvent 处理。

2)return false: 继续传递给子元素的 dispatchTouchEvent 处理。

3)return super.dispatherTouchEvent: 事件默认不会被拦截。

总结: 在 dispatchTouchEvent 内部调用,顾名思义就是判断是否拦截某个事件。(注:ViewGroup 才有的方法,View 因为没有子View了,所以不需要也没有该方法) 。而且这一个事件序列(当前和其它事件)都只能由该 ViewGroup 处理,并且不会再调用该 onInterceptTouchEvent 方法去询问是否拦截。

onTouchEvent

public boolean onTouchEvent(MotionEvent ev)

1)return true: 事件消费,当前事件终止。

2)return false: 交给父 View 的 onTouchEvent。

3)return super.dispatherTouchEvent: 默认处理事件的逻辑和返回 false 时相同。

总结: 在dispatchTouchEvent内部调用

上面3个方法的关系,可以用下面的方法表示:

public boolean dispatchTouchEvent(MotionEvent ev) {
        boolean consume = false;//事件是否被消费
        if (onInterceptTouchEvent(ev)){//调用 onInterceptTouchEvent 判断是否拦截事件
            consume = onTouchEvent(ev);//如果拦截则调用自身的onTouchEvent方法
        }else{
            consume = child.dispatchTouchEvent(ev);//不拦截调用子View的dispatchTouchEvent方法
        }
        return consume;//返回值表示事件是否被消费,true事件终止,false调用父View的onTouchEvent方法
    } 

View的事件分发也是一个顺序执行的操作,自上而下传递,自下而上的回调,直到在某个地方被消费了,下面会按照事件分发的顺序,依次介绍

最后,如果大伙有什么好的学习方法或建议欢迎大家在评论中积极留言哈,希望大家能够共同学习、共同努力、共同进步。

小编在这里祝小伙伴们在未来的日子里都可以 升职加薪,当上总经理,出任CEO,迎娶白富美,走上人生巅峰!!

不论遇到什么困难,都不应该成为我们放弃的理由!

很多人在刚接触这个行业的时候或者是在遇到瓶颈期的时候,总会遇到一些问题,比如学了一段时间感觉没有方向感,不知道该从那里入手去学习,需要一份小编整理出来的学习资料的关注我主页或者点击扫描下方二维码免费领取~

这里是关于我自己的Android 学习,面试文档,视频收集大整理,有兴趣的伙伴们可以看看~

如果你看到了这里,觉得文章写得不错就给个赞呗?如果你觉得那里值得改进的,请给我留言,一定会认真查询,修正不足,谢谢。

Android View绘制及事件(五)View点击事件响应及分发过程详解 它是一个包装了很多触摸事件的实体类,用于存储UI界面与用户交互时的事件信息,如事件类型(按下、抬起、滑动)、x\y坐标值、发生的时间等。触摸点在屏幕上的绝对坐标,坐标值相对于屏幕而言;基于该View的坐标值;getAction,4种常用类型:ACTION_DOWN、ACTION_MOVE、ACTION_UP、ACTION_CANCEL。getActionMasked,多2种:ACTION_POINTER_DOWN、ACTION_POINTER_UP。 阅读详情

相关推荐

逆向实战:从x-mini签名到RPC调用,Frida动态分析小红书加密协议

本文通过实战案例,详细拆解了小红书App的加密协议逆向分析过程。从识别x-mini签名等关键参数入手,结合静态分析与Frida动态Hook技术,追踪到核心的RPC调用入口,并最终封装成可独立调用的RPC函数,为安全研究和协议理解提供了完整的技术路径。

moss5的博客 1035

Android使用ScrollView导致鼠标点击事件无效

Android中, 添加到ScrollView中的控件, 在使用鼠标作为输入设备时, 某些特定的条件下, 子控件的点击事件无效

ansondroider的博客 1684

VSCODE 安装LATEX环境,参数配置,常见问题解决

1 准备Texlive安装包 可以从以下网址下载 texlive 的镜像文件: 华为镜像 阿里镜像 官网 网址中大概文件构成 下载完后我们需要的文件构成(我是2020年下载过了,这次就不重新下载了) 将这个镜像文件进行解压 2 安装Texlive 右键install-tl-windows.bat,单击以管理员身份运行,进入安装界面. 点击左下角的“Advanced”进入高级安装来取消你不需要安装的宏包。 点击“Customize”来取消勾选不需要的宏包。 单是把非中英的语言包取消勾选可以省掉 1G

呆呆象呆呆的博客 6万+

Android事件分发机制【最新、最全、最易懂、由浅入深】

Android事件分发流程 = Activity -> ViewGroup -> View即:1个点击事件发生后,事件先传到Activity、再传到ViewGroup、最终再传到ViewActivity对点击事件的分发机制ViewGroup对点击事件的分发机制View对点击事件的分发机制Activity事件分发机制、ViewGroup事件分发机制、View事件分发机制当一个点击事件发生时,从Activity的事件分发开始(),流程总结如下:三者介绍。

丨康有为丨的博客 1万+

3台虚拟机部署Doris详细文档(含校验步骤)

摘要:本文详细介绍了Apache Doris在3台虚拟机上的集群部署方案。采用1主FE+1从FE+1观察者FE+3BE的混合部署模式,确保元数据高可用性。硬件配置建议测试环境4核16GB内存,生产环境8核64GB内存。部署步骤包括系统环境配置(关闭防火墙、内核参数优化)、FE/BE节点配置启动、集群初始化验证等。重点配置了IP白名单(172.30.0.115)和数据目录(/data/doris)。通过MySQL客户端和WebUI可监控集群状态,实现千万级数据的实时分析能力,后续可通过增加BE节点线性扩展。

weixin_41026747的博客 935

理想汽车智驾方案介绍 4 World model + 强化学习重建自动驾驶交互环境

本帖将以 DrivingSphere 为例来解析这个过程。

地平线开发者 1921

Android View事件分发流程

如果不是则继续循环ViewGroup的dispatchTouchEvent方法,一直到调用super.dispatchTouchEvent或者child.dispatchTouchEvent(child继承于View)activity中调用了getWindow().superDispatchEvent(ev),getWindow获取的对象是window,但是window是一个接口,它的实现类是PhoneWindow,所以这里调用的是PhoneWindow的superDispatchEvent(ev)方法。

a18211246446的博客 431

单片机OTA升级:Bootloader如何多重校验保障APP完整性?

本文详细介绍了单片机OTA升级中Bootloader如何通过CRC校验、数字签名、版本比对和存储位置检查等多重校验机制保障APP完整性。CRC校验作为快速检测数据完整性的核心手段,结合其他安全措施有效防止设备变砖和安全漏洞,确保远程升级的可靠性。

l3m4n的博客 981

Android事件分发机制

Android事件分发机制

qq_27944153的博客 4012

DSSAD自动驾驶行车记录系统体系结构和应用

通过对其感知、决策、控制等模块的详细研究,以及对商业化和消费市场发展趋势的分析,为该领域的研究和实践提供有价值的参考。通过克服技术、安全与隐私、法规与政策等方面的挑战,并紧跟人工智能、云端服务、用户体验等发展趋势,DSSAD系统将更好地适应自动驾驶行业的发展,提供更安全、智能、便捷的驾驶辅助服务。DSSAD体系结构通过数据收集模块、加密链接和数据存储模块和数据读取模块等关键模块的协同作用,构建了一个强大而灵活的自动驾驶数据记录系统,为未来智能出行提供了坚实的技术基础。

一只老虎的专栏 2208

UNet改进(54):当医学图像分割遇上频域学习与自监督

本文提出了一种改进U-Net的方法,通过频域增强模块和代理任务模块提升医学图像分割性能。频域增强模块在傅里叶空间对特征图进行可学习的频率调制,重点增强高频细节特征;代理任务模块通过图像重建约束编码器保留关键信息。两个模块协同工作,在仅增加5%参数量的情况下,形成空间域、频域和重建约束三条互补的信息路径。该方法特别适用于需要精细边缘分割的医学图像任务,预期能提升5%-10%的边缘分割精度,在小样本场景效果更显著。部署时可移除代理任务模块,不影响推理效率。未来可探索空间自适应频域调制和更丰富的代理任务设计。

2501_91516851的博客 227

Android基础学习(二十二)—— View的事件分发(1)

android View事件分发

123 1732

Buck电源设计常见的一些问题(五)MOS管振荡抑制方法(三)

关于开关节点振荡的产生机制和抑制问题,总结了三种抑制方法。第一种方法是利用输入端的高频去耦电容;第二种方法是设计 RC 缓冲电路;第三种方法是优化自举电路的串联电阻。以上三种方法均通过实验加以验证,对开关节点振荡具有很好的抑制作用。应该综合同步 Buck 变换器的各项指标权衡设计。

小幽余生不加糖 1634

Android Framework 客户端 ViewRootImpl 到 View 的事件分发过程

#mermaid-svg-1WVJIbTGSiZqiesM .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-1WVJIbTGSiZqiesM .label text{fill:#333}#mermaid-svg-1WVJIbTGSiZqiesM .node rect,#mermaid-svg-1WVJIbTGSi

刘之帅 742

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

android View和ViewGroup的事件分发过程

1. 点击按钮的事件分发过程 (1)button的dispatchTouchEvent public boolean dispatchTouchEvent(MotionEvent event) { if (!onFilterTouchEventForSecurity(event)) { return false; }

liyang_nash的专栏 319

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Android View的事件分发(一)-事件分发的过程

Android View 虽然不是四大组件,但其并不比四大组件的地位低。而View的核心知识点事件分发机制则是Android开发过程中一个重点也是难点。ScrollView嵌套RecyclerView(或者ListView)的滑动冲突这种问题的理论基础就是事件分发机制。 Android中的事件分发机制也就是View与ViewGroup的对事件的分发与处理。在ViewGroup的内部包含了许多View,而ViewGroup继承自View,所以ViewGroup本身也是一个View。对于事件可以通过ViewGr

m0_56146626的博客 375

android事件分发过程中,由viewgroup传递到view时,怎样决定给哪个view

具体可以参见ViewGroup中的dispatchTouchEvent方法的源码 if (action == MotionEvent.ACTION_DOWN) { if (mMotionTarget != null) { mMotionTarget = null; } if (disallowIntercept || !on...

ElisonX的博客 487

这可能是2024大小厂问的最经典的Android面试题了——事件分发机制、View渲染过程

网上高级工程师面试相关文章鱼龙混杂,要么一堆内容,要么内容质量太浅, 鉴于此我整理了上述安卓开发高级工程师面试题以及答案。希望帮助大家顺利进阶为高级工程师。目前我就职于某大厂安卓高级工程师职位,在当下大环境下也想为安卓工程师出一份力,通过我的技术经验整理了面试经常问的题,答案部分是一篇文章或者几篇文章,都是我认真看过并且觉得不错才整理出来。大家知道高级工程师不会像刚入门那样被问的问题一句话两句话就能表述清楚,所以我通过过滤好文章来帮助大家理解。现在都说互联网寒冬,其实只要自身技术能力够强,咱们就不怕。

2401_84009626的博客 755

android事件分发log打印,【Android】View事件分发、拦截和消费过程解析

目 录(本篇字数:955)案例我们来看一个这样的案例,目的是熟悉android事件分发、拦截的流程,例子如下: 如上图,ViewGroupA内嵌ViewGroupB存放着一个ImageView,一个简单明了的布局,让我们以此来揭开View的事件分发机制。代码非常简单,ViewGroupA和ViewGroupB分别重写了dispatchTouchEvent()、onInterceptTouch...

weixin_35740442的博客 305

android 按钮焦点事件,Android焦点事件分发与传递机制

如果您对TouchEvent事件分发机制不太了解的,可以参考我的这篇文章——安卓TounchEvent事件分发机制。问题:TV端焦点满天飞,如何解决和处理?记得初入TV开发,以为很简单。TV的这些界面与布局太简单了,分分钟就可以把页面搭建出来,处理好,然后就没有然后了。。。。下面我们就从源码来带大家进行安卓TV焦点事件的传递这里先给出Android系统View的绘制流程:依次执行View类里面的如...

weixin_34867001的博客 733

【Android面试查漏补缺】之事件分发机制详解,Android高级工程师面试题-字节跳动

由于文章篇幅原因,我只把面试题列了出来,详细的答案,我整理成了一份PDF文档,这份文档还包括了还有高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 ,帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习。09755460)][外链图片转存中…(img-ofoDE01q-1711809755460)]既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

2401_84007015的博客 1067

模拟面试,解锁大厂 ——从Android的事件分发说起

每天一个面试知识点,文章持续更新,Android模拟面试,解锁大厂一对一面试体验。

2401_89308151的博客 900

Android事件分发机制详解( 传统View和Compose ):从触摸到响应的全过程

在 Android 开发中,触摸事件的分发机制是一个核心知识点,直接影响到应用的用户交互体验。事件的传递和响应贯穿了 View 层级关系,从根视图到子视图形成完整的流程。本文将深入解析事件分发机制,并结合 View 的关系 进行说明。1、用户触摸事件触发:用户在屏幕上进行触摸操作,触发触摸事件(如 DOWN、MOVE、UP)。事件首先传递到 AndroidComposeView,这是 Compose 的根视图,负责接收并初始化事件分发过程。

weixin_44780781的博客 2021

《Android开发艺术探索》3.4.2 事件分发的源码解析(顶级View对点击事件的分发过程)

1、Activity对点击事件的分发过程 点击事件由MotionEvent表示,由Activity的dispatchTouchEvent进行shij事件派发, 具体的工作步骤: Activity内部的Window(实现类PhoneWindow)->DecorView->到达顶级View(根View) 2、顶级View对点击事件的分发过程 具体逻辑:如果顶级ViewGroup拦...

qq_41853047的博客 229

S7-1200 PLC直控AGV实现±3mm精确定点移动

PLC运动控制是工业自动化中实现高精度定位的基础技术,其核心在于实时性、确定性与闭环响应能力。西门子S7-1200凭借PROFINET IRT等时通信、内置PTO脉冲输出及模块化扩展能力,可在无上位机介入下直接调度AGV,支撑微秒级同步、毫秒级闭环调整与负载自适应补偿。该方案突破传统‘PLC仅做逻辑控制’的认知边界,将运动控制权下沉至紧凑型控制器,显著提升柔性产线中AGV的重复定位精度、多机协同稳定性与断电恢复鲁棒性,广泛适用于汽车零部件、锂电模组及3C电子等对节拍和精度敏感的场景。

weixin_34319374的博客 555
上一篇: 【Android Kotlin】lambda的返回语句和匿名函数
下一篇: 【android studio】生成apk包
不秃头de程序猿
博客等级 码龄5年 4089粉丝 1478原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值