文档章节

Android view 事件分发

gavin_jin
 gavin_jin
发布于 2019/02/13 22:35
字数 1138
阅读 18
收藏 0

3 月,跳不动了?>>>

前言

我们在学习View的时候,不可避免会遇到事件的分发,而往往遇到的很多滑动冲突的问题都是由于处理事件分发时不恰当所造成的。因此,深入了解View事件分发机制的原理,对于我们来说是很有必要的。由于View事件分发机制是一个比较复杂的机制。因为我们平时所接触的View都不是单一的View,往往是由若干个ViewGroup组合而成,而事件的分发又是由ViewGroup传递到它的子View的,所以我们先从ViewGroup的事件分发说起。注意,以下源码取自安卓5.0(API 21)。

三个重要方法

public boolean dispatchTouchEvent(MotionEvent ev)

该方法用来进行事件的分发,即无论ViewGroup或者View的事件,都是从这个方法开始的。

public boolean onInterceptTouchEvent(MotionEvent ev)

表示是否拦截当前事件,返回true表示拦截,如果拦截了事件,那么将不会分发给子View。比如说:ViewGroup拦截了这个事件,那么所有事件都由该ViewGroup处理,它内部的子View将不会获得事件的传递。(但是ViewGroup是默认不拦截事件的,这个下面会解释。)注意:View是没有这个方法的,也即是说,继承自View的一个子View不能重写该方法,也无需拦截事件,因为它下面没有View了,它要么处理事件要么不处理事件,所以最底层的子View不能拦截事件。

public boolean onTouchEvent(MotionEvent ev)

这个方法表示对事件进行处理,在dispatchTouchEvent方法内部调用,如果返回true表示消耗当前事件,如果返回false表示不消耗当前事件。

以上三个方法非常重要,贯穿整个View事件分发的流程,它们的关系可以用如下伪代码呈现:

public boolean dispatchTouchEvent(MotionEvent ev){
    boolean handle = false;
    if(onInterceptTouchEvent(ev)){
        handle = onTouchEvent(ev);
    }else{
        handle = child.dispatchTouchEvent(ev);
    }
    return handle;
}

由以上伪代码可得出如下结论:如果一个事件传递到了ViewGroup处,首先会判断当前ViewGroup是否要拦截事件,即调用onInterceptTouchEvent()方法;如果返回true,则表示ViewGroup拦截事件,那么ViewGroup就会调用自身的onTouchEvent来处理事件;如果返回false,表示ViewGroup不拦截事件,此时事件会分发到它的子View处,即调用子View的dispatchTouchEvent方法,如此反复直到事件被消耗掉。

 

view的事件分发

几点说明

  • 主要两个方法 dispatchTouchEventonTouchEvent
  • dispatchTouchEvent 结果返回false会阻断事件传递,返回true会消费掉这次事件,继续下一个事件处理,直到事件处理完。
  • 拦截click事件可以修改onTouch返回true
  • 不可点击的控件默认只有Down的Touch事件,要想有Move和Up事件,必须修改onTouch返回true或者设置clickable为true

viewGroup的事件分发

几点说明

  • 主要方法比View多一个onInterceptTouchEvent,拦截touch事件
  • 事件分发是先从viewGroup,然后再到子View
  • 如果onInterceptTouchEvent返回true,就拦截掉事件,没有子View处理事件的机会了,会走到ViewGroup自身事件处理,基本在onTouch中处理,跟View一样,返回true,继续下个事件,返回false,阻断事件传递
  • 如果点击区域不在子View上,跟onInterceptTouchEvent返回true处理一样,否则会遍历子View,判断是Visible就把事件交给子View处理(注意:这里有模糊点,后面会说
  • 如果子View dispatchTouchEvent 返回true,如果子View clickable为true,返回就肯定是true,就会阻断流程。这样父ViewGroup就不能处理事件了
  • 如果子View dispatchTouchEvent 返回false就会执行所有字View的dispatchTouchEvent,并继续父ViewGroup的事件处理。
  • 让子View dispatchTouchEvent 返回false,只能是clickable为false,这样子View就会阻断事件传递,也就终止了整个事件传递。即子View和父ViewGroup只有Down事件处理

结合上面的理解,我们再来看看Touch事件传递机制流程图

参考

https://blog.csdn.net/suyimin2010/article/details/80958205

https://www.jianshu.com/p/bccf79bd5b5d

 

© 著作权归作者所有

gavin_jin
粉丝 28
博文 127
码字总数 143102
作品 0
海淀
技术主管
私信 提问
加载中

评论(0)

Android 机制篇 - 事件分发机制超详解(🔥🔥🔥🔥🔥🔥🔥🔥)

Android 虽然不是四大组件,但其并不比四大组件的地位低(涉及面的广度和深入甚至比四大组件还复杂🔥)。而View的核心知识点“事件分发机制”则是不少刚入门同学的拦路虎(1、项目中处处遇...

Pepsimaxin
2018/07/12
0
0
一文读懂 Android TouchEvent 事件分发、拦截、处理过程

什么是事件?事件是用户触摸手机屏幕,引起的一系列TouchEvent,包括ACTIONDOWN、ACTIONMOVE、ACTIONUP、ACTIONCANCEL等,这些action组合后变成点击事件、长按事件等。 在这篇文章中,用打L...

传说之美(libill)
2019/09/09
0
0
安卓自定义View进阶-事件分发机制原理

安卓自定义View进阶-事件分发机制原理 之前讲解了很多与View绘图相关的知识,你可以在 安卓自定义View教程目录 中查看到这些文章,如果你理解了这些文章,那么至少2D绘图部分不是难题了,大部...

猴亮屏
2018/05/22
80
0
Android事件分发与责任链模式

一、责任链模式 责任链模式是一种行为模式,为请求创建一个接收者的对象链.这样就避免,一个请求链接多个接收者的情况.进行外部解耦.类似于单向链表结构。 优点: 1. 降低耦合度。它将请求的发...

灰色飘零
01/02
0
0
Android进阶知识:事件分发与滑动冲突(一)

1、前言 Android学习一段时间,需求做多了必然会遇到滑动冲突问题,比如在一个ScrollView中要嵌套一个地图View,这时候触摸移动地图或者放大缩小地图就会变得不太准确甚至没有反应,这就是遇...

Android进阶开发
2019/04/24
0
0

没有更多内容

加载失败,请刷新页面

加载更多

开源:从“复兴”走向“商业化”

在美国版“知乎”Quora上搜“Open Source(开源)”,出来第一条问题是: “Linux的失败真的是因为开源吗?”。其中一个回答给我很多启发: “有些人把安卓和Chrome OS的成功归结于Linux开源...

编辑部的故事
20分钟前
15
0
JavaScript等同于printf / String.Format - JavaScript equivalent to printf/String.Format

问题: I'm looking for a good JavaScript equivalent of the C/PHP printf() or for C#/Java programmers, String.Format() ( IFormatProvider for .NET). 我正在寻找一个等效于C / PHP p......

javail
今天
27
0
什么是Android上的“上下文”? - What is 'Context' on Android?

问题: In Android programming, what exactly is a Context class and what is it used for? 在Android编程中, Context类到底是什么?它的用途是什么? I read about it on the developer......

技术盛宴
今天
26
0
OkHttp配置HTTPS访问+服务器部署

1 概述 OkHttp配置HTTPS访问,核心为以下三个部分: sslSocketFactory() HostnameVerifier X509TrustManager 第一个是ssl套接字工厂,第二个用来验证主机名,第三个是证书信任器管理类.通过OkHtt...

氷泠
今天
20
0
华为P40发布:搭载HMS硬刚谷歌,未涨价抢全球高端机市场

  文连线 Insight,作者向阳,编辑水笙   3 月 26 日晚,华为消费者业务 CEO 余承东登上台,以熟悉的英文口音开启了华为发布会,他说,“这就是我们的 P40 系列。”   以往华为P系列通...

水果黄瓜
今天
30
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部