抬头仰望星空,是否能发现自己的渺小。

伪斜杠青年

人们总是混淆了欲望和理想

Android多点触摸小结

多点触摸下的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条评论

发表评论