在此代码中:
private static MotionEvent e1;
private static float start;
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getActionMasked() == MotionEvent.ACTION_UP) {
MotionEvent e2 = event;
float velocityX = Math.abs((e1.getX() - e2.getX()) / start);
float velocityY = Math.abs((e1.getY() - e2.getY()) / start);
onFling(e1, event, velocityX, velocityY);//BREAKPOINT 2
} else if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
e1 = event;
start = System.currentTimeMillis() / 1000;//BREAKPOINT 1
}
return Game.onTouchEvent(event);
}
如果我在“BREAKPOINT 1”行上放置一个断点,我会得到:
e1.getActionMasked()
等于 ACTION_DOWN
。但是当它停在“BREAKPOINT 2”时,我发现 e1
等于 event
。另外,如果我将 && event != e1
添加到第一个“if”,则会跳过其中的代码。为什么会发生这种情况?
如果你想知道为什么我使用这种方法来替换
onFling()
请参阅:onFling not being called in a costum View
Android在这里做了一些内存优化。由于触摸事件在手势过程中发生了很多次 - Android 不会在每次发生
MotionEvent
时创建 onTouchEvent
实例,而是重用之前的 MotionEvent
实例,因此不会污染堆内存。
由于您在案例中存储了对
MotionEvent
(ACTION_DOWN) 的引用 - 每次调用 ev1
时,您的 onTouchEvent
都会更新。这就是为什么当 ACTION_UP
发生时 - 你的 ev1
等于最新的运动事件。这与过去 ACTION_DOWN
期间的情况相同。
而不是存储
MotionEvent
实例 - 您需要在 x
期间存储
y
和
ACTION_DOWN
坐标
接受的答案是正确的,但如果您确实想要原始实例,您可以通过
MotionEvent.obtain(event)
制作它的副本
在你的情况下是:
e1 = MotionEvent.obtain(event);