Android自定义View——MotionEvent学习笔记

Posted by Csming on 2017-03-18

Android将所有输入事件都放在MotionEvent
包括单点触控、多点触控、鼠标事件、getAction()、getActionMasked()

单点触控

(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

上层View回收事件处理权的时候,ChildView收到一个 ACTION_CANCEL 事件

ACTION_OUTSIDE

一个触摸事件在UI元素的正常范围外发生,则出发ACTION_OUTSIDE

多点触控

  • **ACTION_DOWN:**第一个 手指 初次接触到屏幕 时触发。
  • **ACTION_MOVE:**手指在屏幕上滑动 时触发,会多次触发。
  • **ACTION_UP:**最后一个 手指 离开屏幕 时触发。
  • **ACTION_POINTER_DOWN:**有非主要的手指按下(即按下之前已经有手指在屏幕上)。
  • **ACTION_POINTER_UP:**有非主要的手指抬起(即抬起之后仍然有手指在屏幕上)。

  • **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在手指按下时产生,手指抬起或者事件被取消后消失;是在事件流程中唯一不变的标识;通过getPointerId(int pointerIndex)获取;pointerIndex由getActionIndex获得

index和pointId的变化规则

1、从 0 开始,自动增长。
2、如果之前落下的手指抬起,后面手指的 Index 会随之减小。
3、Index 变化趋向于第一次落下的数值(落下手指时,前面有空缺会优先填补空缺)。
4、对 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() )

历史数据只有 ACTION_MOVE 事件
历史数据单点触控和多点触控均可以用

获取时间发生时间

  • **getDownTime():**手指按下时的时间
  • **getEventTime():**当前事件发生的时间
  • **getHistoricalEventTime(int pos):**历史事件发生的时间

获取压力和接触面积大小

  • **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次事件中的压力大小

大部分设备所使用的电容屏不支持压力检测,但能够大致检测出接触面积
大部分设备的 getPressure() 是使用接触面积来模拟的

鼠标事件

使用getActionMasked() 获得这些事件类型

  • **ACTION_HOVER_ENTER:**指针移入到窗口或者View区域但没有按下
  • **ACTION_HOVER_MOVE:**指针在窗口或View区域移动,但没有按下
  • **ACTION_HOVER_EXIT:**指针移出到窗口或者View区域但没有按下
  • **ACTION_SCROLL:**滚轮滑动,可以出发水平滚动或垂直滚动

输入设备类型判断

  • **TOOL_TYPE_ERASER:**橡皮擦
  • **TOOL_TYPE_FINGER:**手指
  • **TOOL_TYPE_MOUSE:**鼠标
  • **TOOL_TYPE_STYLUS:**手写笔
  • **TOOL_TYPE_UNKNOWN:**未知类型

出处:http://www.gcssloop.com/customview/motionevent