Android自定义控件进阶13-MotionEvent详解
Android MotionEvent 详解,之前用了两篇文章 事件分发机制原理 和 事件分发机制详解 来讲解事件分发,而作为事件分发主角之一的 MotionEvent 并没有过多的说明,本文就带大家了解 MotionEvent 的相关内容,简要介绍触摸事件,主要包括 单点触控、多点触控、鼠标事件 以及 getAction() 和 getActionMasked() 的区别。
Android 将所有的输入事件都放在了 MotionEvent 中,随着安卓的不断发展壮大,MotionEvent 也开始变得越来越复杂,下面是我自己整理的 MotionEvent 大事记:
版本号 | 更新内容 |
---|---|
Android 1.0 (API 1 ) | 支持单点触控和轨迹球的事件。 |
Android 1.6 (API 4 ) | 支持手势。 |
Android 2.0 (API 5 ) | 支持多点触控。 |
Android 3.1 (API 12) | 支持触控笔,鼠标,键盘,操纵杆,游戏控制器等输入工具。 |
以上仅仅是简要的说明几次比较大的变动,细小的修复和更新不计其数,此处就不一一列出了,反正也没人关心这些东西。
MotionEvent 负责集中处理所有类型设备的输入事件,但是由于某些设备使用的几率较小本文会忽略讲解,或者简要讲解,例如:
1、轨迹球只出现在最早的设备上,现代的设备上已经见不到了,本文不再叙述。
2、触控笔和手指处理流程基本相同,不再多说。
3、鼠标在手机上使用概率也比较小,会在文末简要介绍。
单点触控
单点触控就非常简单啦,入门的工程师都会用,上一篇文章也简要介绍过,主要涉及以下几个事件:
事件 | 简介 |
---|---|
ACTION_DOWN | 手指 初次接触到屏幕 时触发。 |
ACTION_MOVE | 手指 在屏幕上滑动 时触发,会多次触发。 |
ACTION_UP | 手指 离开屏幕 时触发。 |
ACTION_CANCEL | 事件 被上层拦截 时触发。 |
ACTION_OUTSIDE | 手指 不在控件区域 时触发。 |
和以下的几个方法:
方法 | 简介 |
---|---|
getAction() | 获取事件类型。 |
getX() | 获得触摸点在当前 View 的 X 轴坐标。 |
getY() | 获得触摸点在当前 View 的 Y 轴坐标。 |
getRawX() | 获得触摸点在整个屏幕的 X 轴坐标。 |
getRawY() | 获得触摸点在整个屏幕的 Y 轴坐标。 |
关于
get
和getRaw
的区别可以参考这一篇文章 安卓自定义View基础-坐标系
单点触控一次简单的交互流程是这样的:
手指落下(ACTION_DOWN) -> 多次移动(ACTION_MOVE) -> 离开(ACTION_UP)
- 本次事例中 ACTION_MOVE 有多次触发。
- 如果仅仅是单击(手指按下再抬起),不会触发 ACTION_MOVE。
针对单点触控的事件处理一般是这样写的:
@Override
public boolean onTouchEvent(MotionEvent event) {// ▼ 注意这里使用的是 getAction(),先埋一个小尾巴。switch (event.getAction()){case MotionEvent.ACTION_DOWN:// 手指按下break;case MotionEvent.ACTION_MOVE:// 手指移动break;case MotionEvent.ACTION_UP:// 手指抬起break;case MotionEvent.ACTION_CANCEL:// 事件被拦截 break;case MotionEvent.ACTION_OUTSIDE:// 超出区域 break;}return super.onTouchEvent(event);
}
相信小伙伴对此已经非常熟悉了,经常使用的东西,我也不啰嗦了。
但其中有两个比较特殊的事件: ACTION_CANCEL
和 ACTION_OUTSIDE
。
为什么说特殊呢,因为它们是由程序触发而产生的,而且触发条件也非常特殊,通常情况下即便不处理这两个事件也没有什么问题。接下来我们就扒一扒它们的真面目:
ACTION_CANCEL
ACTION_CANCEL 的触发条件是事件被上层拦截,然而我们在 事件分发机制原理 一文中了解到当事件被上层 View 拦截的时候,ChildView 是收不到任何事件的,ChildView 收不到任何事件,自然也不会收到 ACTION_CANCEL
了,所以说这个 ACTION_CANCEL
的正确触发条件并不是这样,那么是什么呢?
事实上,只有上层 View 回收事件处理权的时候,ChildView 才会收到一个 ACTION_CANCEL 事件。
这样说可能不太容易理解,咱举个例子?
例如:上层 View 是一个 RecyclerView,它收到了一个
ACTION_DOWN
事件,由于这个可能是点击事件,所以它先传递给对应 ItemView,询问 ItemView 是否需要这个事件,然而接下来又传递过来了一个ACTION_MOVE
事件,且移动的方向和 RecyclerView 的可滑动方向一致,所以 RecyclerView 判断这个事件是滚动事件,于是要收回事件处理权,这时候对应的 ItemView 会收到一个ACTION_CANCEL
,并且不会再收到后续事件。通俗一点?
RecyclerView:儿砸,这里有一个
ACTION_DOWN
你看你要不要。
ItemView :好嘞,我看看。
RecyclerView:噫?居然是移动事件ACTION_MOVE
,我要滚起来了,儿砸,我可能要把你送去你姑父家(缓存区)了,在这之前给你一个ACTION_CANCEL
,你要收好啊。
ItemView :……这是实际开发中最有可能见到
ACTION_CANCEL
的场景了。
ACTION_OUTSIDE
ACTION_OUTSIDE
的触发条件更加奇葩,从字面上看,outside 意思不就是超出区域么?然而不论你如何滑动超出控件区域都不会触发 ACTION_OUTSIDE
这个事件。相信很多魔法师都对此很是疑惑,说好的超出区域呢?
实际上这个事件根本就不是在这里用的,看官方解释(装一下逼):
A movement has happened outside of the normal bounds of the UI element. This does not provide a full gesture, but only the initial location of the movement/touch.
一个触摸事件已经发生了UI元素的正常范围之外。因此不再提供完整的手势,只提供 运动/触摸 的初始位置。
我们知道,正常情况下,如果初始点击位置在该视图区域之外,该视图根本不可能会收到事件,然而,万事万物都不是绝对的,肯定还有一些特殊情况,你可曾还记得点击 Dialog 区域外关闭吗?Dialog 就是一个特殊的视图(没有占满屏幕大小的窗口),能够接收到视图区域外的事件(虽然在通常情况下你根本用不到这个事件),除了 Dialog 之外,你最可能看到这个事件的场景是悬浮窗,当然啦,想要接收到视图之外的事件需要一些特殊的设置。
设置视图的 WindowManager 布局参数的 flags为[
FLAG_WATCH_OUTSIDE_TOUCH
](http://developer.android.com/reference/android/view/WindowManager.La
续集:
- Android自定义控件进阶01-自定义控件开发套路与流程
- Android自定义控件进阶02-Canvas之绘制图形
- Android自定义控件进阶03-Canvas之画布操作
- Android自定义控件进阶04-Canvas之图片文字
- Android自定义控件进阶05-Path之基本操作
- Android自定义控件进阶06-Path之贝塞尔曲线
- Android自定义控件进阶07-Path之完结篇
- Android自定义控件进阶08-PathMeasure详解
- Android自定义控件进阶09-控件核心Matrix原理
- Android自定义控件进阶10-控件核心Matrix Camera
- Android自定义控件进阶11-事件分发机制原理
- Android自定义控件进阶11-事件分发机制原理01
- Android自定义控件进阶12-事件分发机制原理02
- Android自定义控件进阶13-MotionEvent详解
- Android自定义控件进阶14-特殊控件的事件处理方案
粉丝技术交流扣裙
Android自定义控件进阶13-MotionEvent详解相关推荐
- Android自定义控件系列八:详解onMeasure()(二)--利用onMeasure测量来实现图片拉伸永不变形,解决屏幕适配问题
上一篇文章详细讲解了一下onMeasure/measure方法在Android自定义控件时的原理和作用,参看博文:Android自定义控件系列七:详解onMeasure()方法中如何测量一个控件尺寸( ...
- Android 多点触控 MotionEvent详解
相关API 介绍 MotionEvent.getY() 和 MotionEvent.getRawY() 的区别 getY 表示触摸事件在当前的View内的Y 坐标, getRawY表示触摸事件在整个屏 ...
- Android自定义View进阶-MotionEvent详解
欢迎Follow我的GitHub, 关注我的CSDN. 其余参考Android目录 我们微信公众号:杨守乐 推荐文章: 如果你喜欢上了一个程序员小伙,献给所有的程序员女友 学习资料(干货汇集)不断更新 ...
- android鼠标滚轮事件坐标,Android触摸滑动全解(四)——MotionEvent详解
Android触摸滑动全解(四)--MotionEvent详解 在分析View和ViewGroup的触摸事件时,我们已经接触到了MotionEvent类,它是用来存储我们当前手指移动的状态的,比如按下 ...
- Android自定义控件进阶12-事件分发机制原理
Android 事件分发机制详解,在上一篇文章 事件分发机制原理 中简要分析了一下事件分发机制的原理,原理是十分简单的,一句话就能总结:责任链模式,事件层层传递,直到被消费. 虽然原理简单,但是随着 ...
- 【备注】【C24】《Android 3D游戏开发技术详解与典型案例》PDF 下载
[C24]<Android 3D游戏开发技术详解与典型案例>PDF 下载 目前市面上的Android技术书籍还比较少,Android3D游戏开发的书籍更是没有.因此,在现在市面上,Andr ...
- Android高效率编码-第三方SDK详解系列(一)——百度地图,绘制,覆盖物,导航,定位,细腻分解!
Android高效率编码-第三方SDK详解系列(一)--百度地图,绘制,覆盖物,导航,定位,细腻分解! 这是一个系列,但是我也不确定具体会更新多少期,最近很忙,主要还是效率的问题,所以一些有效的东西还 ...
- Android自定义控件进阶03-Canvas之画布操作
Android自定义控件进阶03-Canvas之画布操作 本来想把画布操作放到后面部分的,但是发现很多图形绘制都离不开画布操作,于是先讲解一下画布的基本操作方法. 一.Canvas的常用操作速查表 操 ...
- android+发邮件,Android发送邮件的方法实例详解
Android发送邮件的方法实例详解 时间:2021-05-20 本文实例讲述了Android发送邮件的方法.分享给大家供大家参考,具体如下: 在android手机中实现发送邮件的功能也是不可缺少的. ...
最新文章
- Lumen报class does not exist的mailer坑
- 消除 activity 启动时白屏、黑屏问题
- 【C++】【二】动态数组-Dynamic_linklist
- 利用Excel导入数据到SAP C4C
- 统计单词出现的次数并进行排
- BugkuCTF-MISC题赛博朋克
- 最简单的YUV422转jpg的例程
- mac nginx 指定php.ini,基于Mac自带nginx、php,配置php运行环境
- python中的fun_Python fun中*args,**kwargs参数的含义和用法(*args,**kwargs),Pythonfunargskwargs,及...
- normalize.css下载
- 89C51最小系统典型应用
- Acmer--弱水三千,只取一瓢
- c语言 main()可否省略,main函数中省略返回语句
- 树莓派4B简单使用内容(以移植QT应用为例)
- Revit翻模教程:怎么在体量内绘制圆锥?
- 聊天机器人chatbot搭建及思考(TensorFlow)(附代码)
- 【有利可图网】PS实战系列:制作饼干字特效
- 2018年区块链十大发展势头
- python控制网络摄像头_用Python控制摄像头拍照并发邮件
- ma5822是什么设备_MA5822 配置二层交换