MotionEvent 从 ACTION_UP 更改为 ACTION_DOWN

问题描述 投票:0回答:2

在此代码中:

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
2个回答
4
投票

Android在这里做了一些内存优化。由于触摸事件在手势过程中发生了很多次 - Android 不会在每次发生

MotionEvent
时创建
onTouchEvent
实例,而是重用之前的
MotionEvent
实例,因此不会污染堆内存。

由于您在案例中存储了对

MotionEvent
(ACTION_DOWN) 的引用 - 每次调用
ev1
时,您的
onTouchEvent
都会更新。这就是为什么当
ACTION_UP
发生时 - 你的
ev1
等于最新的运动事件。这与过去
ACTION_DOWN
期间的情况相同。

而不是存储

MotionEvent
实例 - 您需要在
x
 期间存储 
y
ACTION_DOWN

坐标

0
投票

接受的答案是正确的,但如果您确实想要原始实例,您可以通过

MotionEvent.obtain(event)

制作它的副本

在你的情况下是:

e1 = MotionEvent.obtain(event);
© www.soinside.com 2019 - 2024. All rights reserved.