30_Android MotionEvent 类简单介绍

在自定义 View 的过程中,如果设计到控件的触摸事件处理,我们就需要重写 onTouchEvent() 方法。在这个方法中最重要的一个类就是 MotionEvent类。下面会详细介绍一下这个类的各种说明。

获取位置坐标的几个方法

在自定义 View 中,有 View.getLeft()View.getRight()View.getTop()View.getBottom() 等方法,它们的值是本身相对于父控件的距离,和屏幕没有关系

我们都知道,每个触摸事件都代表用户在屏幕上的一个动作,而每个动作必定有其发生的位置。在 MotionEvent 中就有一系列与标触摸事件发生位置相关的函数:

  • getX() / getY():表示触摸点相对于控件本身最左边和最上边的距离——相对坐标
  • getRawX() / getRawY():表示触摸点相对于屏幕的坐标——绝对坐标
函数关系示意图

事件类型

MotionEvent 对象是与用户触摸相关的时间序列,该序列从用户首次触摸屏幕开始,经历手指在屏幕表面的任何移动,直到手指离开屏幕时结束。手指的初次触摸(ACTION_DOWN操作),滑动(ACTION_MOVE操作)和抬起(ACTION_UP)都会创建 MotionEvent 对象,每次触摸时候这三个操作是肯定发生的。

MotionEvent.ACTION_DOWN:当屏幕检测到第一个触点按下之后就会触发到这个事件;

MotionEvent.ACTION_MOVE:当触点在屏幕上移动时触发,触点在屏幕上停留也是会触发的,主要是由于它的灵敏度很高,而我们的手指又不可能完全静止(即使我们感觉不到移动,但其实我们的手指也在不停地抖动) ;

MotionEvent.ACTION_POINTER_DOWN:当屏幕上已经有触点处于按下的状态的时候,再有新的触点被按下时触发;

MotionEvent.ACTION_POINTER_UP:当屏幕上有多个点被按住,松开其中一个点时触发(即非最后一个点被放开时)触发;

MotionEvent.ACTION_UP:当触点松开时被触发;

MotionEvent.ACTION_CANCEL:不是由用户直接触发,由系统在需要的时候触发,例如当父 view 通过使函数 onInterceptTouchEvent() 返回 true,从子 view 拿回处理事件的控制权时,就会给子 view 发一个 ACTION_CANCEL 事件,子 view 就再也不会收到后续事件了。

其它相关方法

getAction ():返回动作类型 ;
getActionMasked():多点触控获取经过掩码后的动作类型;
getActionIndex():多点触控获取经过掩码和平移后的索引;
getSize():指压范围;
getPressure(): 压力值,0-1之间,看情况,很可能始终返回1,具体的级别由驱动和物理硬件决定的 ;
getEdgeFlags():当事件类型是 ActionDown 时可以通过此方法获得边缘标记(EDGE_LEFT,EDGE_TOP,EDGE_RIGHT,EDGE_BOTTOM),但是看设备情况,很可能始终返回 0;
getDownTime() :按下开始时间;
getEventTime(): 事件结束时间;
getPointerCount():获取触控点的数量,比如 2 则可能是两个手指同时按压屏幕;
getPointerId(nID):对于每个触控的点的细节,我们可以通过一个循环执行 getPointerId 方法获取索引;

Pointer

为了可以表示多个触摸点的动作,MotionEvent 中引入了 Pointer 的概念,一个 Pointer 就代表一个触摸点,每个 pointer 都有自己的事件类型,也有自己的横轴坐标值。

一个 MotionEvent 对象中可能会存储多个 pointer 的相关信息,每个 pointer 都会有一个自己的 id 和 index 。pointer 的 id 在整个事件流中是不会发生变化的,但是index会发生变化

MotionEvent 类中的很多方法都是可以传入一个 int 值作为参数的,其实传入的就是 pointer 的 index 值。比如 getX(pointerIndex) 和 getY(pointerIndex) ,此时,它们返回的就是 index 所代表的触摸点相关事件坐标值。

由于 pointer 的 index 值在不同的 MotionEvent 对象中会发生变化,但是 id 值却不会变化。所以,当我们要记录一个触摸点的事件流时,就只需要保存其 id ,然后使用 findPointerIndex(int) 来获得其 index 值,然后再获得其他信息。

getAction 和 getActionMasked

一个 MotionEvent 对象中可以包含多个触摸点的事件。当 MotionEvent 对象只包含一个触摸点的事件时,上边两个函数的结果是相同的,但是当包含多个触摸点时,二者的结果就不同啦。

getAction 获得的 int 值是由 pointer 的 index 值和事件类型值组合而成的,而 getActionWithMasked 则只返回事件的类型值。

getAction() return 0x0105.
getActionMasked() will return 0x0005
其中 0x0100 就是 pointer 的 index 值。

触摸事件onTouch/onTouchEvent

设置触摸事件有两种方式,一种是委托式,一种是回调式

第一种就是将事件的处理委托给监听器处理,你可以定义一个 View.OnTouchListener 接口的子类作为监听器,实现它的 onTouch() 方法,onTouch 方法接收一个 MotionEvent 参数和一个 View 参数。

第二种是重写 View 类(在 Android 中任何一个控件和 Activity 都是间接或者直接继承于 View)自己本身的 onTouchEvent 方法,也就是控件自己处理事件,onTouchEvent 方法仅接收 MotionEvent 参数,这是因为监听器可以监听多个 View 控件的事件。

或者也可以这样写,自定义 View 实现 OnTouchListener 接口,控件自己处理事件。

还有更多手势操作(双击、长按、滑动、滚动)、多点触控等概念。

参考文章:
Android MotionEvent详解
Android的MotionEvent和事件处理

本文章只是作为自己学习和总结所用,如有使用不当之处可随时@我,谢谢

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容

  • 一、 Android分发机制概述: Android如此受欢迎,就在于其优秀的交互性,这其中,Android优秀...
    IT枫阅读 2,428评论 2 9
  • View的事件分发机制 View的事件分发机制简单来说就是将用户与手机屏幕的交互事件交由正确的控件进行处理,从而可...
    蕉下孤客阅读 850评论 0 4
  • 一、前言 Android应用的开发过程不可能不涉及到Touch事件的处理,简单地如设置OnClickListene...
    SparkInLee阅读 7,019评论 3 20
  • 有时候在想我可能是条鱼, 不断的告诉我自己, 你要学会自己游, 游的越远越好, 可回头才发现, 我的天空越来越小,...
    氺尛阅读 232评论 1 2
  • 堂姐来家里玩,带着三个孩子。多年未见,我都分不清谁是老二谁是老三,老大从小就是个漂亮的小女孩。 如今的堂姐身材臃肿...
    墨镜123456阅读 306评论 0 3