Android 具有奇怪坐标的最后一个MotionEvent
我们有益智游戏水果约会,已经有一段时间了。现在我们接到一名球员的报告,他不能触摸菜单上的任何项目。我们给他发了带屏幕调试的特别版本。我们专注于接触,他给了我们这个结果: 每个触摸事件都被截获。我为图片中的每一个“游戏触摸”分割了触摸事件集,左边有红线。每个游戏触摸事件都是这样的:向下(一个或多个拖动)-向上。奇怪的是,在触摸之前,触摸坐标中总是有很大的跳跃 我认为大多数拖动事件只是反弹,但总有至少一个会将坐标跳到左下角。随后,将使用这些不正确的坐标来执行后续事件。当我们检查球员是否在触地时开始触地的同一区域(参见区域参数)内触地时,则没有任何比赛,球员感觉游戏被卡住 报告错误的播放器有THL W200手机。我们以前在很多不同的物理设备上测试过,但从未遇到过这个问题 有人知道为什么会有这么奇怪坐标的运动事件(拖动)吗?你们有谁遇到过吗 我们的游戏是JNI,Java层很薄。MOVETATION事件从这样的视图发送到C++:Android 具有奇怪坐标的最后一个MotionEvent,android,android-ndk,Android,Android Ndk,我们有益智游戏水果约会,已经有一段时间了。现在我们接到一名球员的报告,他不能触摸菜单上的任何项目。我们给他发了带屏幕调试的特别版本。我们专注于接触,他给了我们这个结果: 每个触摸事件都被截获。我为图片中的每一个“游戏触摸”分割了触摸事件集,左边有红线。每个游戏触摸事件都是这样的:向下(一个或多个拖动)-向上。奇怪的是,在触摸之前,触摸坐标中总是有很大的跳跃 我认为大多数拖动事件只是反弹,但总有至少一个会将坐标跳到左下角。随后,将使用这些不正确的坐标来执行后续事件。当我们检查球员是否在触地时开始
@Override
public boolean onTouchEvent(final MotionEvent aEvent)
{
final int action = aEvent.getAction();
queueEvent(new Runnable()
{
int motionEvent = -1;
public void run()
{
if (action == MotionEvent.ACTION_DOWN)
{
motionEvent = ANDROID_TOUCH_ACTION_DOWN;
}
else if (action == MotionEvent.ACTION_UP)
{
motionEvent = ANDROID_TOUCH_ACTION_UP;
}
else if (action == MotionEvent.ACTION_MOVE)
{
motionEvent = ANDROID_TOUCH_ACTION_MOVE;
}
SBCEngine.engine_on_touch((int) aEvent.getX(), (int) aEvent.getY(), motionEvent);
}
});
return true;
}
class MotionEventRunnable implements Runnable
{
private int mPointerID;
private int mActionID;
private int mX, mY;
//-----------------------------------------------------
public MotionEventRunnable(int aPointerID, int aActionID, int aX, int aY)
{
mPointerID = aPointerID;
mActionID = aActionID;
mX = aX;
mY = aY;
}
//-----------------------------------------------------
@Override
public void run()
{
// send to native
SBCEngine.engine_on_touch(mPointerID, mX, mY, mActionID);
}
}
终于找到了解决方案,所以如果有人感兴趣 上述代码不安全。在处理事件之前,引用的事件对象可能会更改。这段代码取自《将厄运和地震移植到Android》一书,你们可以在网上找到类似的代码。直到昨天,它在所有测试过的设备上都有效。它在THL W200设备上失败 我将代码更改为:
@Override
public boolean onTouchEvent(final MotionEvent aEvent)
{
// get masked (not specific to a pointer) action
int maskedAction = aEvent.getActionMasked();
switch (maskedAction)
{
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
{
// get pointer index from the event object
int pointerIndex = aEvent.getActionIndex();
// get pointer ID
int pointerId = aEvent.getPointerId(pointerIndex);
//Log.d("POINTER", "pointer down: ID = " + pointerId + " x=" + aEvent.getX(pointerIndex) + ", y = " + aEvent.getY(pointerIndex));
queueEvent(new MotionEventRunnable(pointerId, maskedAction,
(int) aEvent.getX(pointerIndex),
(int) aEvent.getY(pointerIndex)));
break;
}
case MotionEvent.ACTION_MOVE:
{
// a pointer was moved
int size = aEvent.getPointerCount();
for (int i = 0; i < size; i++)
{
// Get the pointer ID and index
int pointerId = aEvent.getPointerId(i);
int pointerIndex = aEvent.findPointerIndex(pointerId);
//Log.d("POINTER", "pointer move: ID = " + pointerId + " x=" + aEvent.getX(pointerIndex) + ", y = " + aEvent.getY(pointerIndex));
queueEvent(new MotionEventRunnable(pointerId, maskedAction,
(int) aEvent.getX(pointerIndex),
(int) aEvent.getY(pointerIndex)));
}
break;
}
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_CANCEL:
{
// get pointer index from the event object
int pointerIndex = aEvent.getActionIndex();
// get pointer ID
int pointerId = aEvent.getPointerId(pointerIndex);
//Log.d("POINTER", "pointer up: ID = " + pointerId + " x=" + aEvent.getX(pointerIndex) + ", y = " + aEvent.getY(pointerIndex));
queueEvent(new MotionEventRunnable(pointerId, maskedAction,
(int) aEvent.getX(pointerIndex),
(int) aEvent.getY(pointerIndex)));
break;
}
}
return true;
}
代码更复杂,因为它还处理多点触摸,但关键是我缓存了所有必需的值:指针id、动作、x和y。它解决了我的问题