网络测速全解析之一:自定义View基础知识(九)

本文详细介绍了Android中MotionEvent的使用,包括单点和多点触控的事件流程,如何获取手指接触面积和压力大小,以及处理鼠标事件和判断输入设备类型。特别指出,这些功能可能因设备和系统版本差异而表现不一致,使用时需做设备适配检查。
摘要由CSDN通过智能技术生成

一、MotionEvent讲解:

单点触控:

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

方法:

方法简介
getAction()获取事件类型。
getX()获得触摸点在当前 View 的 X 轴坐标。
getY()获得触摸点在当前 View 的 Y 轴坐标。
getRawX()获得触摸点在整个屏幕的 X 轴坐标。
getRawY()获得触摸点在整个屏幕的 Y 轴坐标。

一次简单的交互流程:

手指落下(ACTION_DOWN) -> 多次移动(ACTION_MOVE) -> 离开(ACTION_UP)

两个特殊的事件:ACTION_CANCEL和ACTION_OUTSIDE

 

多点触控

解决多个手指同时按住屏幕的事件区分方式:编号

事件简介
ACTION_DOWN第一个 手指 初次接触到屏幕 时触发。
ACTION_MOVE手指 在屏幕上滑动 时触发,会多次触发。
ACTION_UP最后一个 手指 离开屏幕 时触发。
ACTION_POINTER_DOWN有非主要的手指按下(即按下之前已经有手指在屏幕上)。
ACTION_POINTER_UP有非主要的手指抬起(即抬起之后仍然有手指在屏幕上)。
以下事件类型不推荐使用------------------
ACTION_POINTER_1_DOWN第 2 个手指按下,已废弃,不推荐使用。
ACTION_POINTER_2_DOWN第 3 个手指按下,已废弃,不推荐使用。
ACTION_POINTER_3_DOWN第 4 个手指按下,已废弃,不推荐使用。
ACTION_POINTER_1_UP第 2 个手指抬起,已废弃,不推荐使用。
ACTION_POINTER_2_UP第 3 个手指抬起,已废弃,不推荐使用。
ACTION_POINTER_3_UP第 4 个手指抬起,已废弃,不推荐使用。

方法:

方法简介
getActionMasked()与 getAction() 类似,多点触控必须使用这个方法获取事件类型。
getActionIndex()获取该事件是哪个指针(手指)产生的。
getPointerCount()获取在屏幕上手指的个数。
getPointerId(int pointerIndex)获取一个指针(手指)的唯一标识符ID,在手指按下和抬起之间ID始终不变。
findPointerIndex(int pointerId)通过PointerId获取到当前状态下PointIndex,之后通过PointIndex获取其他内容。
getX(int pointerIndex)获取某一个指针(手指)的X坐标
getY(int pointerIndex)获取某一个指针(手指)的Y坐标

PointId

追踪事件流,请认准 PointId,这是唯一官方指定标准,不要相信 ActionIndex 那个小婊砸。

getPointerId(int pointerIndex)

 

历史数据(批处理)

由于我们的设备非常灵敏,手指稍微移动一下就会产生一个移动事件,所以移动事件会产生的特别频繁,为了提高效率,系统会将近期的多个移动事件(move)按照事件发生的顺序进行排序打包放在同一个 MotionEvent 中,与之对应的产生了以下方法:

事件简介
getHistorySize()获取历史事件集合大小
getHistoricalX(int pos)

获取第pos个历史事件x坐标

(pos < getHistorySize())

getHistoricalY(int pos)

获取第pos个历史事件y坐标

(pos < getHistorySize())

getHistoricalX (int pin, int pos)

获取第pin个手指的第pos个历史事件x坐标

(pin < getPointerCount(), pos < getHistorySize() )

getHistoricalY (int pin, int pos)

获取第pin个手指的第pos个历史事件y坐标

(pin < getPointerCount(), pos < getHistorySize() )

注意:

  1. pin 全称是 pointerIndex,表示第几个手指,此处为了节省空间使用了缩写。

  2. 历史数据只有 ACTION_MOVE 事件。

  3. 历史数据单点触控和多点触控均可以用。

 

获取事件发生的时间

方法简介
getDownTime()获取手指按下时的时间。
getEventTime()获取当前事件发生的时间。
getHistoricalEventTime(int pos)获取历史事件发生的时间。
  1. pos 表示历史数据中的第几个数据。( pos < getHistorySize() )

  2. 返回值类型为 long,单位是毫秒。

 

获取压力(接触面积大小)

MotionEvent支持获取某些输入设备(手指或触控笔)的与屏幕的接触面积和压力大小,主要有以下方法:

描述中使用了手指,触控笔也是一样的。

方法简介
getSize ()获取第1个手指与屏幕接触面积的大小
getSize (int pin)获取第pin个手指与屏幕接触面积的大小
getHistoricalSize (int pos)获取历史数据中第1个手指在第pos次事件中的接触面积
getHistoricalSize (int pin, int pos)获取历史数据中第pin个手指在第pos次事件中的接触面积
getPressure ()获取第一个手指的压力大小
getPressure (int pin)获取第pin个手指的压力大小
getHistoricalPressure (int pos)获取历史数据中第1个手指在第pos次事件中的压力大小
getHistoricalPressure (int pin, int pos)获取历史数据中第pin个手指在第pos次事件中的压力大小
  1. pin 全称是 pointerIndex,表示第几个手指。(pin < getPointerCount() )

  2. pos 表示历史数据中的第几个数据。( pos < getHistorySize() )

注意:

1、获取接触面积大小和获取压力大小是需要硬件支持的。

2、非常不幸的是大部分设备所使用的电容屏不支持压力检测,但能够大致检测出接触面积。

3、大部分设备的 getPressure() 是使用接触面积来模拟的。

4、由于某些未知的原因(可能系统版本和硬件问题),某些设备不支持该方法。

我用不同的设备对这两个方法进行了测试,然而不同设备测试出来的结果不相同,之后经过我多方查证,发现是系统问题,有的设备上只有 getSize() 能用,有的设备上只有 getPressure() 能用,而有的则两个都不能用。

由于获取接触面积和获取压力大小受系统和硬件影响,使用的时候一定要进行数据检测,以防因为设备问题而导致程序出错。

 

鼠标事件

由于触控笔事件和手指事件处理流程大致相同,所以就不讲解了,这里讲解一下与鼠标相关的几个事件:

事件简介
ACTION_HOVER_ENTER指针移入到窗口或者View区域,但没有按下。
ACTION_HOVER_MOVE指针在窗口或者View区域移动,但没有按下。
ACTION_HOVER_EXIT指针移出到窗口或者View区域,但没有按下。
ACTION_SCROLL滚轮滚动,可以触发水平滚动(AXIS_HSCROLL)或者垂直滚动(AXIS_VSCROLL)

注意:

1、这些事件类型是 安卓4.0 (API 14) 才添加的。

2、使用 ` getActionMasked()` 获得这些事件类型。

3、这些事件不会传递到 onTouchEvent(MotionEvent) 而是传递到 onGenericMotionEvent(MotionEvent)

 

输入设备类型判断

输入设备类型判断也是安卓4.0 (API 14) 才添加的,主要包括以下几种设备:

设备类型简介
TOOL_TYPE_ERASER橡皮擦
TOOL_TYPE_FINGER手指
TOOL_TYPE_MOUSE鼠标
TOOL_TYPE_STYLUS手写笔
TOOL_TYPE_UNKNOWN未知类型

使用 getToolType(int pointerIndex) 来获取对应的输入设备类型,pointIndex可以为0,但必须小于 getPointerCount()。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值