多点触摸下的Id与Index关系示意
PS: 随时间变更,google可能已经变更此规则,无需在意。
依次按下A,B,C三个手指,此时[手指id]与[id所在的数组index]对应关系为:
然后松开B手指,数组index会重新调整,但是id不会变:
再次加入B手指,此时理论上id会调整成这样:
但实际上,Id的复用会导致index的重新调整,会变成这样:
所以在遍历的时候,依旧是:
总的来说,规律就是:
- Index永远是连续的,在抬起和放下时会变 ,而id不会变。所以Index用于遍历,id用于行为追踪
- ACTION_MOVE时无法得知哪个具体的点被移动(getIndex只会返回一个值,若两个手指在移动呢?),所以获得的index是无效的,只能遍历数组index按id进行操作
常用语句块:
用于ACTION_DOWN时,先获取index,再捕获id进行具体跟踪操作:
int actionIndex = event.getActionIndex();
trackingPointerId = event.getPointerId(actionIndex);
在ACTION_MOVE时遍历所有pointer进行操作:
for (int i = 0; i < event.getPointerCount(); i++) { pointerId = event.getPointerId(i); //TODO }
PS:多点触控的onTouchEvent方法中,应使用MotionEvent.getActionMasked() 替代MotionEvent.getAction() ,原因看源码:
/** * Return the masked action being performed, without pointer index information. * Use {@link #getActionIndex} to return the index associated with pointer actions. * @return The action, such as {@link #ACTION_DOWN} or {@link #ACTION_POINTER_DOWN}. */public final int getActionMasked() { return nativeGetAction(mNativePtr) & ACTION_MASK; }
在多点的情况下,使用getActionMasked会更安全,getActionMasked获取的信息中不包含index信息,从而不会影响获取的事件准确性。
多点触控常见的三种类型
接力型
一个手指按下时,响应该手指,按下第二个手指时,第二个手指接替第一手指的工作继续响应。即:同一时刻,只有一个pointer起作用,也就是最新的pointer。
实现方式:追踪一个pointer id进行操作,每次在ACTION_POINTER_DOWN/UP时将追踪的id更新为最新的ID,在后续的ACTION_MOVE等操作中根据这个id来进行行为判断。
举例:ListView RecyleView
配合型/协作型
所有按下的手指共同产生作用,比如双指手势,多指手势。
实现方式:在ACTION_DOWN/POINTER_DOWN、ACTION_UP/POINTER_UP 时使用所有poiner的左边共同更新焦点坐标,在ACTION_MOCE等之后的事件中使用焦点坐标进行行为判断。
举例:双指左滑/右滑、三指唤出菜单、五指唤出菜单,均需要以各个点的位置计算公共焦点位置,再进行处理。
独立型
各个pointer做不同的事,互不影响。
实现方式:在每个ACTION_DOWN/POINTER_DOWN中记录每个pointer的id,根据id(不要根据index,上面有说index是会发生变化的),在后续的ACTION_MOVE等事件中针对每个id进行单独的跟踪。
举例:电子白板的10点书写,每个手指画出轨迹不一样的线条。
PS:以上来自扔物线,本人仅做复述以及部分补充。
本站由以下主机服务商提供服务支持:
0条评论