View的事件分发机制

本文详细解析了Android系统中点击事件的传递流程,包括事件的分发、拦截与消费过程,并通过源码分析了Activity、Window及View之间的交互机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、点击事件的传递规则
    点击事件的分发:对MotionEvent事件的分发过程,也即当一个MotionEvent产生时,系统需要将其传递给一个具体的View来处理,这个过程即为分发过程;
1.1 3个重要方法
    public boolean dispatchTouchEvent(MotionEvent ev)
    用来进行事件分发。返回结果受当前view的onTouchEvent和下级View的dispatchTouchEvent方法的影响,表示是否消费该事件。
1.1.1 事件分发何时终止
     1)return true:事件分发给当前View并由dispatchTouchEvent进行消费,同时事件会停止向下传递;
     2)return fasle:事件会分发给事件源Activity或者父级的onTouchEvent进行消费,停止分发;
    3)return super.dispatchTouchEvent,事件会自动分发给当前view的onInterceptTouchEvent方法
    public boolean onInterceptTouchEvent(MotionEvent ev)
    在上述dispatchTouchEvent方法内调用用来判断是否拦截某事件。返回结果表示是否拦截当前事件。
1.1.2 事件拦截何时终止
1)return  true:则表示事件进行拦截,并将拦截到的事件交由当前View的onTouchEvent进行处理;
    2)return false:则表示事件放行,当前View上的事件会被传递到子View中,再由子View的dispatchTouchEvent开始对事件进行分发;
    3)return super.onInterceptTouchEvent,事件默认会被拦截,并将拦截到的事件交由当前View的onTouchEvent进行处理;
public boolean onTouchEvent(MotionEvent ev)
    在dispatchTouchEvent方法内调用用来处理点击事件,返回结果表示是否消费当前事件;如果不消费,则在同一事件序列中,当前view无法再次接收到事件;
1.1.3 事件消费何时终止    
1)return true:则表示接收并消费当前事件;
    2)return false:则表示该事件会向上传递,并由上层View的onTouchEvent来接收;如果传递到上层的onTouchEvent还是返回false,说明该事件无效,而且接收不到下一次事件;
    3)return super.onTouchEvent:跟返回false相同;
这3个方法的关系如下:

    1)对于ViewGroup来说,点击事件产生后,首先会传递给它,这时它的dispatchTouchEvent方法被调用,如果这个viewgroup的onInterceptTouchEvent方法返回true表示此viewgroup要拦截当前事件,接着事件会被它的onTouchEvent处理;如果这个viewgroup的onInterceptTouchEvent方法返回false表示它不拦截当前事件,此时事件会继续传递给它的子元素处理,接着子元素的dispatchTouchEvent被调用
    2)对于view来说,如果view设置onTouchListener,那么此时onTouchListener的onTouch方法会被回调;这时事件如何处理跟onTouch方法返回值有关:如果返回false,则当前view的onTouchEvent方法被调用;如果返回true,onTouchEvent方法不会被调用---->view的onTouchListener优先级比onTouchEvent高。
    3)MotionEvent事件产生后,其传递顺序:Activity--->Window---->View;
    4)ViewGroup默认不拦截任何事件;
    5)View没有onInterceptTouchEvent方法,一旦点击事件传递给它,其onTouchEvent方法会立刻被执行;
    6)View的onTouchEvent默认都会消费该事件;
二、事件分发的源码解析
2.1 Activity对点击事件的分发过程
    当MotionEvent事件发生时,该事件最先传递给当前Activity,此时由Activity的dispatchTouchEvent进行事件分发:具体工作是由Activity内部window来完成,然后window才把事件交给DecorView来处理(最顶级view);

  1)事件开始交给window进行分发:见第二个if中的superDispatchTouchEvent方法;该方法返回true,说明事件已经消费;返回false说明事件没有消费,这时Activity的onTouchEvent方法被调用;
2.2 Window如何将事件传递给ViewGroup
    Window是抽象类,同时superDispatchTouchEvent方法也是抽象方法--->Window类的具体实现类是PhoneWindow,在PhoneWindow类中superDispatchTouchEvent具体实现了将事件传递给DecorView。源代码如下:

2.3 顶级View对点击事件的分发过程
    1)首先看ViewGroup对点击事件的分发过程:也即dispatchTouchEvent(MotionEvent ev)方法被调用,第一步查看点击事件是否被拦截;如果拦截,就自己处理;如果不拦截,就交给它的子View来消费事件;
2)viewgroup不拦截事件时,会遍历viewgroup的所有子元素,然后判断子元素是否能够接收到点击事件,标准:子元素是否在播动画和点击事件坐标是否落在子元素区域。
     如果满足这两个条件,事件会传递给它处理。
 2.4 View对点击事件的处理过程
   1)较为简单,因为其没有子元素无法向下传递事件,也即view只能消费事件;
     2)判断view有没有设置OnTouchListener,如果设置OnTouchListener而且onTouch方法返回true,此时view的onTouchEvent不会被调用,此时view的dispatchTouchEvent返回true;如果没有设置OnTouchListener以及onTouch方法返回false,view的onTouchEvent被调用。
3)onTouchEvent实现:只要View的CLICKABLE和LONG_CLICKABLE有一个为true,那么view就会消耗此事件,此时onTouchEvent方法返回true;然后在ACTION_UP事件发生时,会触发performClick方法,如果View设置OnClickListener,那么在performClick中调用onClick方法。
    
    
    
    
    
    
    
    
    
    
资源下载链接为: https://pan.quark.cn/s/9648a1f24758 这个HTML文件是一个专门设计的网页,适合在告白或纪念日这样的特殊时刻送给女朋友,给她带来惊喜。它通过HTML技术,将普通文字转化为富有情感和创意的表达方式,让数字媒体也能传递深情。HTML(HyperText Markup Language)是构建网页的基础语言,通过标签描述网页结构和内容,让浏览器正确展示页面。在这个特效网页中,开发者可能使用了HTML5的新特性,比如音频、视频、Canvas画布或WebGL图形,来提升视觉效果和交互体验。 原本这个文件可能是基于ASP.NET技术构建的,其扩展名是“.aspx”。ASP.NET是微软开发的一个服务器端Web应用程序框架,支持多种编程语言(如C#或VB.NET)来编写动态网页。但为了在本地直接运行,不依赖服务器,开发者将其转换为纯静态的HTML格式,只需浏览器即可打开查看。 在使用这个HTML特效页时,建议使用Internet Explorer(IE)浏览器,因为一些老的或特定的网页特效可能只在IE上表现正常,尤其是那些依赖ActiveX控件或IE特有功能的页面。不过,由于IE逐渐被淘汰,现代网页可能不再对其进行优化,因此在其他现代浏览器上运行可能会出现问题。 压缩包内的文件“yangyisen0713-7561403-biaobai(html版本)_1598430618”是经过压缩的HTML文件,可能包含图片、CSS样式表和JavaScript脚本等资源。用户需要先解压,然后在浏览器中打开HTML文件,就能看到预设的告白或纪念日特效。 这个项目展示了HTML作为动态和互动内容载体的强大能力,也提醒我们,尽管技术在进步,但有时复古的方式(如使用IE浏览器)仍能唤起怀旧之情。在准备类似的个性化礼物时,掌握基本的HTML和网页制作技巧非常
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值