Search code examples
android

MotionEvent changes from ACTION_UP to ACTION_DOWN


In this code:

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);
}

If I put a break point on the "BREAKPOINT 1" line, I get that: e1.getActionMasked() equals ACTION_DOWN. But when it stops in "BREAKPOINT 2" I get that e1 equals event. Also if I add && event != e1 to the first "if" the code in it is skipped.Why is this happening?

If you want to know why I am using this approach to replace onFling() see this: onFling not being called in a costum View


Solution

  • Android does some memory optimization here. Since touch events happen really a lot during the gesture - instead of creating MotionEvent instance every time onTouchEvent happens, Android reuses previous MotionEvent instance, so you don't pollute your heap memory.

    Since you store the reference to MotionEvent (ACTION_DOWN) in your case - your ev1 is getting updated every time onTouchEvent is called. That's why when ACTION_UP happens - your ev1 equals to the latest motion event. It is the same instance as it used to be during ACTION_DOWN.

    Instead of storing MotionEvent instance - you need to store x and y coordinates during ACTION_DOWN