博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android-View进阶-事件分发机制原理
阅读量:7112 次
发布时间:2019-06-28

本文共 1908 字,大约阅读时间需要 6 分钟。

简简单单讲清楚android事件分发。

什么叫事件分发机制 ?

事件分发是:当发生了一个事件时,在屏幕上找到一个合适的控件来处理这个事件的过程。

因为一个界面上控件如此之多,发生一个事件后总要寻找一个合适来处理事件吧。这个过程就叫做事件分发的机制。

常见事件

那么屏幕上都会发生什么事件呢?来看下经常要处理的4种事件(这些事件在android中会被封装成 MotionEvent 对象):

事件 简介
ACTION_DOWN 手指 初次接触到屏幕 时触发。
ACTION_MOVE 手指 在屏幕上滑动 时触发,会会多次触发。
ACTION_UP 手指 离开屏幕 时触发。
ACTION_CANCEL 事件 被上层拦截 时触发。

屏幕中的控件

为了在屏幕中如何寻找合适的处理事件的控件,我们先来看下屏幕中都有什么控件。

假设我们写了如下的一个布局:

View结构:

上面的代码运行到界面上由图中这几部分组成:

可以看到在上面的View结构中莫名多出来的两个东西,PhoneWindow 和 DecorView ,这两个我们并没有在Layout文件中定义过,但是为什么会存在呢?

1. PhoneWindow
PhoneWindow是 Window 的唯一实现类,是所有视图的最顶层容器,视图的外观和行为都归他管,不论是背景显示,标题栏还是事件处理都是他管理的范畴。
2. DecorView
DecorView是 PhoneWindow 的一个内部类,就是跟在 PhoneWindow 身边专业为 PhoneWindow 服务的,除了自己要干活之外,也负责消息的传递,PhoneWindow 的指示通过 DecorView 传递给下面的 View,而下面 View 的信息也通过 DecorView 回传给 PhoneWindow。

事件分发流程

在如上图View的树形结构中,事件发生时,最先由Activity接收,然后再一层层的向下层传递,直到找到合适的处理控件。大致如下:

但是如果事件传递到最后的View还是没有找到合适的View消费事件,那么事件就会向相反的方向传递,最终传递给Activity,如果最后 Activity 也没有处理,本次事件才会被抛弃:

Android中事件具体是怎样进行分发的

当事件发生时,ViewGroup会在dispatchTouchEvent方法中先看自己能否处理事件,如果不能再去遍历子View查找合适的处理控件。如果到最后result还是false,表示所有的子View都不能处理,才会调用自身的onTouchEvent来处理。

根据上面提到的原理,ViewGroup事件传递的伪代码如下:

public boolean dispatchTouchEvent(MotionEvent ev) {    boolean result = false;             // 默认状态为没有消费过    if (!onInterceptTouchEvent(ev)) {   // 如果没有拦截交给子View        result = child.dispatchTouchEvent(ev);    }    if (!result) {                      // 如果事件没有被消费,询问自身onTouchEvent        result = onTouchEvent(ev);    }    return result;}

为了方便理解,这里贴出一张网上的别人的一张图:

  • 红色箭头方向表示事件分发方向。
  • 绿色箭头方向表示事件回传方向。

上面的流程中存在部分不合理内容,请大家选择性接受。
事件返回时 dispatchTouchEvent 直接指向了父View的 onTouchEvent 这一部分是不合理的,实际上它仅仅是给了父View的 dispatchTouchEvent 一个 false 返回值,父View根据返回值来调用自身的 onTouchEvent。
ViewGroup 是根据 onInterceptTouchEvent 的返回值来确定是调用子View的 dispatchTouchEvent 还是自身的 onTouchEvent, 并没有将调用交给 onInterceptTouchEvent。

如果在遍历过程中,发现了有可以处理事件的控件,就停止事件的传递,事件被消耗。

本文参考资料:

推荐阅读:

推荐阅读:

image

image

转载地址:http://aimhl.baihongyu.com/

你可能感兴趣的文章
Ubuntu安装ping工具
查看>>
我的友情链接
查看>>
jetty远程调试
查看>>
SCCM2012R2之三独立站点安装
查看>>
职业生涯规划:如何选择一家适合自己的公司?
查看>>
viewport大白话
查看>>
我的友情链接
查看>>
在Oracle中使用命令crs_stat -t,输出结果里资源名称后缀的含义
查看>>
如何查询HP-UX主机防火墙状态
查看>>
我的友情链接
查看>>
HTML实现置顶-->火箭置顶
查看>>
nginx缓存命中率统计
查看>>
DirectAccess(3)—Inter Server配置
查看>>
iptables内网应用
查看>>
让KVM飞——初识
查看>>
VMWare ESXi 5.1 安装在U盘
查看>>
CAD库中统计PBN运行航路条数和总距离
查看>>
Addthis分享插件后url乱码的解决办法
查看>>
arm汇编之 bne与beq
查看>>
【BZOJ】1176: [Balkan2007]Mokia
查看>>