因此,简单地说,我用于多点触控的处理程序会崩溃并抛出“IllegalArgumentException:pointerIndex out of range”。
我试着捕捉错误,但后来意识到 (x, y) 将默认为 (min.x, max.y),在我的例子中是 (0.0, 480.0)。
经过相当多的混乱之后,我发现该错误仅在发送垃圾邮件时出现,但可以通过足够快地交替点击两个不同的位置(但仍然足够慢以在常规多点触控游戏中发生) .
这是 onTouch 方法:
public boolean onTouch(View v, MotionEvent event) {
synchronized (this) {
int pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
int pointerId = event.getPointerId(pointerIndex);
TouchEvent touchEvent;
// pointerId fix
if (pointerId >= event.getPointerCount() && pointerId > 0)
pointerId--;
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
touchEvent = touchEventPool.newObject();
touchEvent.type = TouchEvent.TOUCH_DOWN;
touchEvent.pointer = pointerId;
try {
touchEvent.x = touchX[pointerId] = (int) (event
.getX(pointerId) * scaleX);
touchEvent.y = touchY[pointerId] = (int) (event
.getY(pointerId) * scaleY);
} catch (IllegalArgumentException e) {
Log.d("multiTouchHandler", e.toString() + ":: PID = "
+ pointerId);
}
isTouched[pointerId] = true;
touchEventsBuffer.add(touchEvent);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
touchEvent = touchEventPool.newObject();
touchEvent.type = TouchEvent.TOUCH_UP;
touchEvent.pointer = pointerId;
try {
touchEvent.x = touchX[pointerId] = (int) (event
.getX(pointerIndex) * scaleX);
touchEvent.y = touchY[pointerId] = (int) (event
.getY(pointerIndex) * scaleY);
} catch (IllegalArgumentException e) {
Log.d("multiTouchHandler", e.toString() + ":: PID = "
+ pointerId);
}
isTouched[pointerId] = false;
touchEventsBuffer.add(touchEvent);
return false;
case MotionEvent.ACTION_MOVE:
int pointerCount = event.getPointerCount();
for (int i = 0; i < pointerCount; i++) {
touchEvent = touchEventPool.newObject();
touchEvent.type = TouchEvent.TOUCH_DRAGGED;
touchEvent.pointer = pointerId;
try {
touchEvent.x = touchX[pointerId] = (int) (event
.getX(pointerIndex) * scaleX);
touchEvent.y = touchY[pointerId] = (int) (event
.getY(pointerIndex) * scaleY);
} catch (IllegalArgumentException e) {
Log.d("multiTouchHandler", e.toString() + ":: PID = "
+ pointerId);
}
isTouched[pointerId] = false;
touchEventsBuffer.add(touchEvent);
}
break;
case MotionEvent.ACTION_CANCEL:
}
return true;
}
}
从 Log.d 输出中看起来发生的事情是,有时 pointerId 会被分配给下一个可用指针(例如 1),但实际的指针数据会存储在前一个指针位置(0)中。
通过检查pointerId 是否超出当前pointerCount 的范围,如果超出,我至少可以用两行代码解决两个手指的问题。
// pointerId fix
if (pointerId >= event.getPointerCount() && pointerId > 0)
pointerId--;
我不确定这是否真的解决了这个问题,但它似乎适用于两指多点触控控制,例如用于触摸屏 fps 游戏的控制。我自己的测试表明,它能够准确无误地确定两个点的触摸,并存储正确的 (x, y) 值
有没有更好的解决方案,或者指针 ID 的多点触控 API 使用真的那么糟糕?如果有人想知道,这是在 4.0.3 设备上。