ple:Android 多点触控 "pointer index out of range" - 为什么?

ple:Android Multitouch "pointer index out of range" - Why?

我知道还有一些关于该主题的其他话题,但没有问题可以将问题减少到几行代码:

@Override
public boolean onTouchEvent(MotionEvent event) {

    int count = event.getPointerCount();
    for (int i = 0; i < count; ++i) {
        int id = event.getPointerId(i);
        event.getX(id); // Exception here
    }

}

代码只是获取指针的数量,请求指针 ID 并使用它来读取指针的 x 值。

当我使用多个手指时,代码会抛出 "IllegalArgumentException: pointerIndex out of range"。

所有可能的操作都会引发异常("ACTION_DOWN"、"ACTION_POINTER_DOWN"、"ACTION_UP"、"ACTION_POINTER_UP" 和 "ACTION_MOVE")

示例:

我放下一根手指,然后放下第二根手指,然后向上一根手指 => 现在第二根手指的每一个动作都失败了。

完成 onTouchEvent 测试:

@Override
public boolean onTouchEvent(MotionEvent event) {

    int action = (event.getActionMasked() & MotionEvent.ACTION_MASK);
    int count = event.getPointerCount();

    String actionStr = null;

    switch (action) {
        case MotionEvent.ACTION_DOWN:
            actionStr = "down";
            break;
        case MotionEvent.ACTION_UP:
            actionStr = "up";
            break;
        case MotionEvent.ACTION_MOVE:
            actionStr = "move";
            break;
        case MotionEvent.ACTION_POINTER_UP:
            actionStr = "pointer up";
            break;
        case MotionEvent.ACTION_POINTER_DOWN:
            actionStr = "pointer down";
            break;
    }

    try {

        for (int i = 0; i < count; ++i) {
            int id = event.getPointerId(i);
            event.getX(id);
            //event.getY(id);
        }

    } catch (Exception e) {
        Log.d("_FAIL_", actionStr);
    }

    return true;
}

你应该这样做:

event.getX(event.findPointerIndex(id));

编辑

来自Android Developer Site

The order in which individual pointers appear within a motion event is undefined. Thus the index of a pointer can change from one event to the next, but the pointer ID of a pointer is guaranteed to remain constant as long as the pointer remains active. Use the getPointerId() method to obtain a pointer's ID to track the pointer across all subsequent motion events in a gesture. Then for successive motion events, use the findPointerIndex() method to obtain the pointer index for a given pointer ID in that motion event.

希望对您有所帮助。