关于 MotionEvent 的笔记
来源:互联网 发布:手机淘宝店铺怎么开 编辑:程序博客网 时间:2024/05/21 22:26
概述
MotionEvent 不仅仅用来表示 触摸事件, 还可以是 鼠标/trackball/pen 等等事件.
一个MotionEvent包含的信息: ACTION_DOWN 这种, 坐标, 压力, 大小, 方向.
两个相邻的 MotionEvent 的 时间间隔差不多是 10–40 ms 之间.
- 即, 这个时间段 其实也够了;
- 即 每秒种保证了 25—100 次的刷新, 即使ui上的更新, 也感觉比较顺滑的了.
关于pointerId和pointerIndex
- 每一个MotionEvent 都 包含了 当前所有 触摸点(Pointer)的信息—-即使它没有动.
- 即如果有多个手指在屏幕上面, 即使只有一个手指动, 但是这个MotionEvent中包含了所有的pointer的信息(坐标/压力等).
- 有两个不同的东西:
- pointerId
- 在一个pointer的down到up之间, 其值恒定;
- 其值可能会大于 pointers的总数;
- 因为中途可能会有pointer离开, 其对应的pointerId就空了(当然可能会被新down下去的pointer拿去用);
- pointerId失效后, 可能会被新down下去的pointer拿去用.
- pointerIndex
- 一个pointer在down到up之间时, 其pointerIndex值是可能会有变化的.
- 比如, 总共有4个pointers.
一个pointer的pointerIndex为3,
但此时pointerIndex为1的手指up了, 那么总共变成了3个pointers了,
此时这个pointer的pointerIndex可能就会被调整为2了.
- pointerId
关于pointerId
- 每一个触摸点 都有一个 pointerid—-这个是唯一的, 一直有效的.(但在up/pointer_up后会失效, 可能会别新按下去的手指拿去)
获取 pointerId 的办法:
int getPointerId(int pointerIndex)//参数是0什么的, 最大为: int getPointerCount()-1----注意, 在每一个gesture中, 一个手指的 pointerIndex 可能会不同, 但在 pointerId 却是一样的. 一个 pointerId 的有效期: 从这个手指 down/pointer_down 到 up/pointer_up 这一段时间之内. 注意: pointerId 也是按 0,1,2,3...之类的序号排下去的. 一个手指的pointerId 在 up/pointer_up 后就无效了, 其可能会被 其它新 按下去的 手指拿去用. ----这个要注意! ----即 pointerId 并非在 一个gesture 中一直唯一表明某一个手指的, 而仅仅是指 一个手指down/pointer_down 到 up/pointer_up 这一段时间之内 的id值.
关于pointerIndex
- pointerIndex 则是从0–getPointerCount() 之间;
- 一个 pointer 的 index 其 会随着 情况的变化而变化, —-即不恒定.
- 比如,
总共有4个pointers.
一个pointer的pointerIndex为3,
但此时pointerIndex为1的手指up了, 那么总共变成了3个pointers了,
此时这个pointer的pointerIndex可能就会被调整为2了.
- 比如,
以下这些方法的参数用的都是 pointerIndex, 而不是 pointer id:
getX(int), getY(int), getAxisValue(int), getPointerId(int), //参数是pointerIndex, 返回的是 pointerIdgetToolType(int)
关于 pointerIndex 和 pointerId 之间的转换:
- 方法: getPointerId(int) , 我们通过 pointer index 来得到这个 pointer的id
- 方法: findPointerIndex(int) , 我们可以 通过 pointer id 得到 其 index.
列几个重要的方法吧(有些前面已列过了)
如下:
int getPointerCount()int getPointerId(int pointerIndex)int findPointerIndex(int pointerId)int getPointerId(int pointerIndex)int getPointerIdBits() 这个方法是, 拿到当前这个MotionEvent的所有手指的id号.----这些id号 按位运算 放到 一个 int数据中. 比如, 有3个手指, 其对应的id为 2,3,5, 则返回的是 0000 0000 0010 1100, 即, 0x2c了. ----注意的是 pointerId 其实很朴素, 就是0, 1, 2, 3.....之类排下去的.
关于 Action 和 ActionMask 和 ActionIndex:
关于Action的简述:
内部用于标注事件类型的方式是:—-有一个int型数据用于记录 一个pointer的pointerIndex和action.
低版本直接做为MotionEvent的数据成员:
private int mAction;
高版本MotionEvent中需要通过jni来查询:
private static native int nativeGetAction(long nativePtr)
这个 int 型数据 实现上只用到了 低两位, 比如:
0x0101 ---- 高8位, 表示 pointerIndex 低8位, 表示 事件类型, ACTION_DOWN/ACTION_UP/ACTION_POINTER_DOWN 之类.
相关几个方法:
int getAction() 返回的 0x0101 这种.int getActionMasked() 返回的是 低8位, 即 事件类型, ACTION_DOWN/ACTION_UP/ACTION_POINTER_DOWN 之类.int getActionIndex() 返回的是 高8位, 即pointerIndex. 发生了 ACTION_POINTER_DOWN 和 ACTION_POINTER_UP 的 pointer 的 index.
内部标识位 的 详解:
action 类型:
public static final int ACTION_MASK = 0xff; //用于获取低8位.public static final int ACTION_DOWN = 0;public static final int ACTION_UP = 1;public static final int ACTION_MOVE = 2;public static final int ACTION_CANCEL = 3;public static final int ACTION_OUTSIDE = 4;public static final int ACTION_POINTER_DOWN = 5;public static final int ACTION_POINTER_UP = 6;public static final int ACTION_HOVER_MOVE = 7;public static final int ACTION_SCROLL = 8;public static final int ACTION_HOVER_ENTER = 9;public static final int ACTION_HOVER_EXIT = 10;
pointerIndex:
public static final int ACTION_POINTER_INDEX_MASK = 0xff00; //用于获取低2字节中的高8位.public static final int ACTION_POINTER_INDEX_SHIFT = 8; //因为要从高8位移到低8位.以下这些都过时了----而且是错的, 不要按这个来了.public static final int ACTION_POINTER_1_DOWN = ACTION_POINTER_DOWN | 0x0000; = 0x0005;public static final int ACTION_POINTER_2_DOWN = ACTION_POINTER_DOWN | 0x0100; = 0x0105;public static final int ACTION_POINTER_3_DOWN = ACTION_POINTER_DOWN | 0x0200; = 0x0205;public static final int ACTION_POINTER_1_UP = ACTION_POINTER_UP | 0x0000; = 0x0006;public static final int ACTION_POINTER_2_UP = ACTION_POINTER_UP | 0x0100; = 0x0106;public static final int ACTION_POINTER_3_UP = ACTION_POINTER_UP | 0x0200; = 0x0206;public static final int ACTION_POINTER_ID_MASK = 0xff00;public static final int ACTION_POINTER_ID_SHIFT = 8;
注意一点:
- ACTION_DOWN 的点 离开时 可能是以 ACTION_POINTER_UP 离开
- —-因为可能并不是最后一个点离开的.
- 而 ACTION_POINTER_DOWN 的点, 可能以 ACTION_UP 离开的
- —-因为虽然并不是第0个点按下去, 但可能是最后一个点离开的.
- 所以, * getAction 拿到的 ACTION_UP 并不总是 第0个按下去点的 离开事件.*
- ACTION_DOWN 的点 离开时 可能是以 ACTION_POINTER_UP 离开
关于 Batch
概述:
由于, 我们每次通过 MotionEvent 的去处理 多点触摸事件, 很麻烦:
int getPointerCount()int getPointerId(int pointerIndex)int findPointerIndex(int pointerId)int getPointerId(int pointerIndex)
所以, 思路上: 将 多个 motion event 放到一个 MotionEvent中.
- —-即 批处理 的思想.
- —-注意:
- 这个 批处理 只在 事件类型为 ACTION_MOVE 时 才有的,
- 而 ACTION_DOWN/ACTION_UP/ACTION_CANCEL/ACTION_POINTER_DOWN/ACTION_POINTER_UP 都是没有的.
详述:
一个 MotionEvent 中包含的事件有:
- 最后一个motion event事件 + getHistorySize个历史 motion event事件.
这个方法, 注意一下:
float nativeGetAxisValue(long nativePtr, int axis, int pointerIndex, int historyPos)
涉及的方法有:
float getX() 本质是: nativeGetAxisValue(mNativePtr, AXIS_X, 0, HISTORY_CURRENT); 即, 返回的是 **第0个手指** **最后一个**motion event 的x轴位置, float getX(int pointerIndex) 本质是: nativeGetAxisValue(mNativePtr, AXIS_X, pointerIndex, HISTORY_CURRENT); 即, 返回的是 **第pointerIndex个** 手指 **最后一个**motion event 的x轴位置.float getHistoricalX(int pointerIndex, int pos) 本质是: nativeGetAxisValue(mNativePtr, AXIS_X, pointerIndex, pos); 即, 返回的是 第pointerIndex个 手指 第pos个 motion event 的x轴位置.final long getHistoricalEventTime(int pos) ----这里我就不多贴出来了, 实际上, 不仅仅可以 获得历史 motion event 的 坐标/时, 还可以 获得 压力 等等信息. 这里就不多说了.int getHistorySize() 获得 这个 MotionEvent 中 包含了多少个 历史motion event事件. 只有当 事件类型为 ACTION_MOVE 时, 其返回才不为0; 否则返回0.
处理示例:
void printSamples(MotionEvent ev) { final int historySize = ev.getHistorySize(); final int pointerCount = ev.getPointerCount(); for (int h = 0; h < historySize; h++) { System.out.printf("At time %d:", ev.getHistoricalEventTime(h)); for (int p = 0; p < pointerCount; p++) { System.out.printf(" pointer %d: (%f,%f)", ev.getPointerId(p), ev.getHistoricalX(p, h), ev.getHistoricalY(p, h)); } } System.out.printf("At time %d:", ev.getEventTime()); for (int p = 0; p < pointerCount; p++) { System.out.printf(" pointer %d: (%f,%f)", ev.getPointerId(p), ev.getX(p), ev.getY(p)); }}注意: 先处理 历史motion event事件(序号越为0, 时间就越早), 最后 再来处理 最近的 motion event事件.
2 0
- 关于 MotionEvent 的笔记
- 关于motionevent的使用
- 关于MotionEvent的小知识
- 关于android的MotionEvent详细讲解
- 关于MotionEvent.ACTION_CANCEL带来的滑动问题解决
- 关于MotionEvent的getX()与getRawX()的那些事
- (转载) 关于MotionEvent.ACTION_UP无法被响应的问题
- 关于MotionEvent.ACTION_UP无法被响应的问题
- 关于android中MotionEvent认识
- 关于android中MotionEvent认识
- 关于android中MotionEvent认识
- MotionEvent的理解
- MotionEvent的几个值
- MotionEvent
- MotionEvent
- onTouchEvent(MotionEvent event)的使用
- View的onInterceptTouchEvent(MotionEvent ev)和dispatchTouchEvent(MotionEvent ev) 解析
- 【MotionEvent】亲测MotionEvent中getX()和getRawX()的区别
- avi视频格式
- Hdu 4288 Coder(从小到大排列的集合中下标模5为3的数的和)
- 推荐系统的误区
- Fragment切换页面思路整理
- Linux编码问题
- 关于 MotionEvent 的笔记
- 有用的机器学习链接(持续更新)
- android自定义View之重写View来实现全新的控件
- ReactNative 学习第二节 环境搭建
- bzoj 3242: [Noi2013]快餐店 dfs&递推
- 拦截导弹
- 选择排序和冒泡排序
- 二进制中1的个数----位运算
- 蓝桥杯 PREV-6-翻硬币