Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android SimpleOnGestureListener.onFling getting a null MotionEvent

Tags:

android

touch

I am trying to detect a fling event on a simple Android application, but the first MotionEvent argument is always null. Why is the onFling method being called with a null argument? The Android documentation says that it gets called when a fling event occurs with the initial on down MotionEvent and the matching up MotionEvent.

class MyGestureDetector extends SimpleOnGestureListener {
    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        // e1 always == null, return early a null reference exception
        if (e1 == null) {
            return false;
        }
        if (e1.getY() - e2.getY() > 120) {
            handleFlingEvent();
            return true;
        }
        return false;
    }
}

The main Activity has this onTouchEvent method:

GestureDetector flingDetector = new GestureDetector(new MyGestureDetector());

@Override
public boolean onTouchEvent(MotionEvent event) {
    if (flingDetector.onTouchEvent(event)) {
        return true;
    }
    return super.onTouchEvent(event);
}
like image 521
mcrumley Avatar asked Nov 11 '10 04:11

mcrumley


2 Answers

I first ran into this issue with Android 4.0 as my code works fine in all the prior versions. After taking a cue from the suggestions here, I've found an easy workaround is to just keep track of the onDown event and use it in place of the first param of onFling in case it happens to be null.

public class MySimpleGestureListener extends SimpleOnGestureListener {
    protected MotionEvent mLastOnDownEvent = null;

    @Override
    public boolean onDown(MotionEvent e) {
        mLastOnDownEvent = e;
        return true;//super.onDown(e);
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        if (e1==null)
            e1 = mLastOnDownEvent;
        if (e1==null || e2==null)
            return false;
        float dX = e2.getX()-e1.getX();
        float dY = e2.getY()-e1.getY();
        ...rest of code
    }

    ...rest of class
}
like image 85
Uncle Code Monkey Avatar answered Nov 15 '22 17:11

Uncle Code Monkey


I've got the same problem with custom view and OnGestureListener onFling. Found out this:

Whether or not you use GestureDetector.SimpleOnGestureListener, you must always implement an onDown() method that returns true.

Sourced from http://developer.android.com/training/custom-views/making-interactive.html

like image 33
Olga Avatar answered Nov 15 '22 17:11

Olga