我最近收到了针对我的应用程序的崩溃报告,在查看了堆栈跟踪后,意识到我的多点触控控件存在问题。
发生的事情是这样的:
我正试图记录仅4指的手指按压。不再。我希望有效地“忽略”任何超过4的东西。
因此,我正在做这样的事情:
@Override
public boolean onTouchEvent(MotionEvent event) {
pointerCount = event.getPointerCount();
if (pointerCount <= 4){
actionMask = event.getActionMasked();
pointerIndex = event.getActionIndex();
pointerID = event.getPointerId(pointerIndex);
//etc.............
因此,如果手指超过4个,我就不会在onTouch中运行任何东西。
这似乎工作正常,它通常不会对手指5,6等“行动”。所以那里一切都很好。 (我说'一般'因为下面的内容).....
问题
然而,如果我说下,6个手指向下,然后将它们抬起,放下的最后一个手指的指针ID为5.这不是一个真正的问题因为我在 action_up <中没有做任何事情/ em>或 action_pointer_up 。
在 action_pointer_down 中,90%的时间我得到预期的行为,其中任何一个手指放下的ID都只有0到3之间。
但是,如果您在屏幕上放置5个或更多手指并反复快速点击屏幕,最终会将ID分配给 action_pointer_down 事件,是4或更多(我见过4,5,6和7)所以当它试图将这些值放入xList nad yList数组时,它会以越界异常崩溃。
这是一个问题,因为在action_pointer_down中,我将手指的x和y保存到我创建的几个数组中。 (我需要此信息以便稍后执行某些操作)这些数组的大小均为4(因此索引0到3)。像这样:
case MotionEvent.ACTION_POINTER_DOWN:{
try{
if (isJumpPressed(event.getX(pointerIndex),event.getY(pointerIndex))){
//Jump here
}
else if (isLeftPressed(event.getX(pointerIndex),event.getY(pointerIndex))){
//Move left here
}
else if(isRightPressed(event.getX(pointerIndex),event.getY(pointerIndex))){
//Move right here
}
//****These lines randomly fail if the pointerID >=4
xList[pointerID]=event.getX(pointerIndex);
yList[pointerID]=event.getY(pointerIndex);
}
catch(Exception e){
Log.v("Error","Oops, something's wrong");
}
break;
}
}
这是为什么?这是Multi-touch API中的错误还是我不理解的东西。在正常使用中,错误通常不会发生,但我可以自己轻松触发它并由用户找到它,因此任何帮助都将受到赞赏。我希望任何手指向下事件只能获得0-3的ID。除非我误解了什么。
答案 0 :(得分:1)
不要依赖指针的ID是顺序的,或者根本与当前触摸屏幕的指针数量直接相关。 ID是一个标识符,不是识别手指向下或手指向下的方式。
The documentation表示ID只是介于0和getPointerCount() - 1
之间的值,并且ID在特定手势中使用。因此,如果Android将您的快速点击解释为单个手势,则使用相同手指的多个点击可能会有不同的ID。
对于您的特定情况,听起来Map<int, float>
可能更适合将特定指针映射到其X和Y坐标。使用地图肯定会修复你的越界异常。
例如:
Map<Integer, Float> xMap = new HashMap<>();
// ...
case MotionEvent.ACTION_POINTER_DOWN:
// ...
xMap.put(pointerID, event.getX(pointerIndex);
稍后您可以使用xMap.get(2)
检索ID为2的指针的值。