Android事件分发备忘

前言

事件的分发是面试的必考题,也是Android作为一个移动系统,与用户交互的基础。由于整个事件分发比较繁杂,这里做一个总结,以作备忘。

事实上,Android系统中的事件分发机制是一个委托者模型。我们先从最简单的看起。

三个方法

在Android的摸触事件中,我们通常关注的方法有三个。

dispatchTouchEvent(MotionEvent event)
onInterceptTouchEvent(MotionEvent event)
onTouchEvent(MotionEvent event)

这个三个方法组成了Android系统中,各个层级的事件分发,拉截和处理。


我们先从最熟悉的讲起:

View

View 作为视图层级中的最上层。是事件分发的终点

dispatchTouchEvent

View 的 作为最上层的控件,事件不再需要分发,因此,在dispatchTouchEvent中,几乎一定会调用 View 本身的 onTouchEvent(排除enable被关闭),同时将onTouchEvent的返回结果return。

onTouchEvent

在onTouchEvent中,Android实现了View的点击拖动等事件。

onInterceptTouchEvent

由于View 作为最上层视图不会再向更上层传递事件,所以没有onInterceptTouchEvent 方法。


ViewGroup

ViewGroup 作为视图层级中View的父控件。是事件分发的中间环节

dispatchTouchEvent

ViewGroup 的 作为中层的控件,不仅需要接收底层的事件(底层会调用ViewGroup的dispatchTouchEvent方法),还要将事件分发到上层,因此,在dispatchTouchEvent中,ViewGroup需要优先考虑onInterceptTouchEvent,如果事件被拦截,则直接调onTouchEvent,如果未被拦截,就需要调用所有子View的dispatchTouchEvent。

onTouchEvent

ViewGroup继承了View的onTouchEvent。有两种情况,ViewGroup的onTouchEvent方法会调用。

  1. ViewGroup的onInterceptTouchEvent返回true,表示ViewGroup决定拦截这个事件。
  2. ViewGroup的所有ChildView的onTouchEvent全部返回false,此时表示,没有任何一个ChildView愿意处理这个事件。所以,事件会返回给上层ViewGroup。同理,如果ViewGroup不处理这个事件,返回false,事件会继续往上传。
onInterceptTouchEvent
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (ev.isFromSource(InputDevice.SOURCE_MOUSE)
                && ev.getAction() == MotionEvent.ACTION_DOWN
                && ev.isButtonPressed(MotionEvent.BUTTON_PRIMARY)
                && isOnScrollbarThumb(ev.getX(), ev.getY())) {
            return true;
        }
        return false;
    }

返回true表拦截,false不拉截。

一图流:


看了上面的图,关于事件传递的所有疑惑应该都不存在了。接下来我们来探讨一下,事件分发的最上层是什么。

其实从上图中我们就可以看到,最上层的是Activity,Activity中有dispatchTouchEvent和onTouchEvent方法。因为Activity处于最上层,所以不存在拦截的问题。dispatchTouchEvent和onTouchEvent与ViewGroup的流程相同。


这里补充一点小小的信息。Activity与View的关系。同样是一图流:

以上。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏中国Android研究院

进阶必备-Android事件分发机制

或许你会问,“为什么我一定要知道View的事件分发机制?”。因为我们在实际开发的过程中,经常会遇到多层的View互相嵌套以后,对某一个View进行滑动的时候,特...

14240
来自专栏每日一篇技术文章

VR+全景播放器+头控讲解-06

在UIView上面布局我们可以使用UIButton UIView UIImageView等,但是是在3D场景中,我们不能使用UIView,我们要使用平面几何当视...

9110
来自专栏向治洪

android view事件分发机制

首先我们先写个简单的例子来测试View的事件转发的流程~ 1、案例 为了更好的研究View的事件转发,我们自定以一个MyButton继承Button,然后把跟事...

19260
来自专栏Android Note

Android-录屏APP该怎么实现?

18320
来自专栏懒人开发

dispatchTouchEvent事件分发浅析(四)Intercept拦截

上一篇,我们大体理解了分发的过程,并且简单做了点击,分析了执行顺序 这篇我们来看下 Intercept拦截

9820
来自专栏知识分享

Android之网络摄像头

实现的功能就是两个手机在一个局域网内可以互相观看对方的摄像头图像,当然如果都是连接公网那么就能远程互看了,,,,和视频聊天差不多,,不过没有声音,,,,,,,,...

79980
来自专栏开发之途

Android 解决 View 的滑动冲突

关于 Android 的 TouchEvent 事件分发机制可以看这里:Java_Android_Learn,本文讲解的是如何去解决 View 之间的滑动冲突

13610
来自专栏向治洪

android viewgroup事件分发机制

今天给大家代码ViewGroup事件分发的源码解析~~凡是自定义ViewGroup实现各种滑动效果的,不可避免的会出现很多事件的冲突,对ViewGroup事件分...

20760
来自专栏CodingBlock

Android查缺补漏(View篇)--事件分发机制

事件分发机制是Android中非常重要的一个知识点,同时也是难点,相信到目前为止很多Android开发者对事件分发机制并没有一个非常系统的认识,当然也包括博主个...

28170
来自专栏郭霖

Android事件分发机制完全解析,带你从源码的角度彻底理解(下)

记得在前面的文章中,我带大家一起从源码的角度分析了Android中View的事件分发机制,相信阅读过的朋友对View的事件分发已经有比较深刻的理解了。 还未阅读...

287100

扫码关注云+社区

领取腾讯云代金券