概述
多点触控 ( Multitouch,也称 Multi-touch ),即同时接受屏幕上多个点的人机交互操作,多点触控是从 Android 2.0 开始引入的功能,在 Android 2.2 时对这一部分进行了重新设计。
相关事件
相关方法
自己自己手动进行计算,判断手指的抬起和落下
兼容2.2以前:
1 | String TAG = "Gcs"; |
看几个关键点:
1.action 与 Index 的获得
我们在 前面了解过,Android中的事件一般用最后8位来表示事件类型,再往前8位来表示Index。
例如多指触控的按下事件,其事件类型是 0x00000005, 其Index标志位是 0x00000005,随着更多的手指按下,其中变化的部分是 Index 标志位,最后两位是始终不变的,所以我们只要能将这两个分离开就行了。
取得事件类型(action)
这个非常简单,ACTION_MASK=0x000000ff, 与 getAction() 进行按位与操作后保留最后8位内容(十六进制每一个字符转化为二进制是4位)。
例如:
0x00000105 & 0x000000ff = 0x00000005
1 | // 获取事件类型 |
取得事件索引(index)
ACTION_POINTER_INDEX_MASK = 0x0000ff00
ACTION_POINTER_INDEX_SHIFT = 8
首先让 getAction() 与 ACTION_POINTER_INDEX_MASK 按位与之后,只保留 Index 那8位,之后再右移8位,最终就拿到了 Index 的真实数值。例如:
0x00000105 & 0x0000ff00 = 0x00000100
0x00000100 » 8 = 0x00000001
1 | // 获取index编号 |
只考虑兼容 2.2 以上的版本:
1 | String TAG = "Gcs"; |
index 和 pointId 的变化规则
在 2.2 版本以上,我们可以通过 getActionIndex() 轻松获取到事件的索引(Index),但是这个事件索引的变化还是有点意思的,Index 变化有以下几个特点:
1、从 0 开始,自动增长。
这个前面说过了。
2、如果之前落下的手指抬起,后面手指的 Index 会随之减小。
注意最后两次触发的事件,它的 Index 都是 1,这样也比较容易解释,当原本的第 2 个手指抬起后,屏幕上就只剩下两个手指了,之前的第 3 个手指就变成了第 2 个,于是抬起时触发事件的 Index 为 1,即之前落下的手指抬起,后面手指的 Index 会随之减小。
3、Index 变化趋向于第一次落下的数值(落下手指时,前面有空缺会优先填补空缺)。
4、对 move 事件无效。
这个也比较容易理解,我们所取得的 Index 属性实际上是从事件上分离下来的,但是 move 事件始终为 0x00000002,也就是说,在 move 时不论你移动哪个手指,使用
getActionIndex()
获取到的始终是数值 0。既然 move 事件无法用事件索引(Index)区别,那么该如何区分 move 是那个手指发出的呢?这就要用到 pointId 了,pointId 和 index 最大的区别就是 pointId 是不变的,始终为第一次落下时生成的数值,不会受到其他手指抬起和落下的影响。
pointId 与 index 的异同
Move相关事件
actionIndex 与 pointerIndex
在 move 中无法取得 actionIndex 的,我们需要使用 pointerIndex 来获取更多的信息,例如某个手指的坐标:
1 | getX(int pointerIndex) |
实际上这个 pointerIndex 和 actionIndex 区别并不大,两者的数值是相同的,你可以认为 pointerIndex 是特地为 move 事件准备的 actionIndex。
pointerIndex 与 pointerId
这两个数值使用以下两个方法相互转换:
通常情况下,pointerIndex 和 pointerId 是相同的,但也可能会因为某些手指的抬起而变得不同。
遍历多点触控
先来一个简单的,遍历出多个手指的 move 事件:
1 | String TAG = "Gcs"; |
通过遍历 pointerCount 获取到所有的 pointerIndex,同时通过 pointerIndex 来获取 pointerId,可以通过不同手指抬起和按下后移动来观察 pointerIndex 和 pointerId 的变化。
在多点触控中追踪单个手指:
要实现追踪单个手指还是有些麻烦的,需要同时使用上 actionIndex, pointerId 和 pointerIndex,例如,我们只追踪第2个手指,并画出其位置:
1 | /** |