Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OnFling MotionEvent e1 null?

Tags:

android

Ok. This thing almost drives me crazy.

Some days ago I could implement the code below and the toast was successfully called when I tried to swipe right or left.

However, now it can't be called, because the e1 is always null!

How could this happen? I try this code on the emulator, but a user reports me, that it also doesn't work on real device.

public class SwipeGestureListener extends GestureDetector.SimpleOnGestureListener{

    private static final int SWIPE_MIN_DISTANCE = 150;
    private static final int SWIPE_MAX_OFF_PATH = 100;

    private static final int SWIPE_THRESHOLD_VELOCITY = 100;
    private final Activity activity;
    protected MotionEvent mLastOnDownEvent = null;

    public SwipeGestureListener(Activity activity) {
        this.activity = activity;
    }

    @Override
    public boolean onDown(MotionEvent e) {
        mLastOnDownEvent = e;
        System.out.println(e);
        return super.onDown(e);
    }

    @Override   
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        System.out.println(e1 + " " + e2);
        if (e1==null)
            e1 = mLastOnDownEvent;
        if (e1==null || e2==null)
            return false;

        float dX = e2.getX()-e1.getX();
        float dY = e2.getY()-e1.getY();

        if (Math.abs(dY)<SWIPE_MAX_OFF_PATH && Math.abs(velocityX)>=SWIPE_THRESHOLD_VELOCITY && Math.abs(dX)>=SWIPE_MIN_DISTANCE ) {

            if (dX>0) {
                Toast.makeText(activity.getApplicationContext(), "Right Swipe", Toast.LENGTH_SHORT).show();
                activity.fetchPrevious();
            } else {
                Toast.makeText(activity.getApplicationContext(), "Left Swipe", Toast.LENGTH_SHORT).show();
                activity.fetchNext();
            }

            return true;
        } 

        return false;
    }

}

The code that implement the gesture:

final GestureDetector gdt = new GestureDetector(this, new SwipeGestureListener(this));
listview.setOnTouchListener(new OnTouchListener(){

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        gdt.onTouchEvent(event);
        return false;
        }

});
like image 950
Rendy Avatar asked Jun 30 '13 13:06

Rendy


1 Answers

I tried your code and indeed it didn't work, then I changed the GestureDetector to the newer/updated API "GestureDetectorCompat" and changed a few further things: Used the GestureDetector.OnGestureListener instead of the OnSimpleGestureListener, onDown() should return true and then it worked. I can't explain it to you, what was the exact problem. But the change lines seemed to be problematic. Maybe someone can explain the underlying problem. Have a look at the code, which is working:

public class MainActivity extends Activity {
   ImageView imageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageView= (ImageView) findViewById(R.id.imageView1);

        final GestureDetectorCompat gdt = new GestureDetectorCompat(this, new SwipeGestureListener(this));
        imageView.setOnTouchListener(new OnTouchListener(){

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return gdt.onTouchEvent(event);
                }

        });

    }




    public class SwipeGestureListener implements GestureDetector.OnGestureListener{

        private static final int SWIPE_MIN_DISTANCE = 150;
        private static final int SWIPE_MAX_OFF_PATH = 100;

        private static final int SWIPE_THRESHOLD_VELOCITY = 100;
        private final Activity activity;
        protected MotionEvent mLastOnDownEvent = null;

        public SwipeGestureListener(Activity activity) {
            this.activity = activity;
    }

        @Override
        public boolean onDown(MotionEvent e) {
            mLastOnDownEvent = e;
            System.err.println("ondown");
            //System.out.println(e);
            return true;
        }

        @Override   
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            System.err.println("onFling");
            System.out.println(e1 + " " + e2);
            if (e1==null)
                e1 = mLastOnDownEvent;
            if (e1==null || e2==null)
                return false;

            float dX = e2.getX()-e1.getX();
            float dY = e2.getY()-e1.getY();

            if (Math.abs(dY)<SWIPE_MAX_OFF_PATH && Math.abs(velocityX)>=SWIPE_THRESHOLD_VELOCITY && Math.abs(dX)>=SWIPE_MIN_DISTANCE ) {

                if (dX>0) {
                    Toast.makeText(activity.getApplicationContext(), "Right Swipe", Toast.LENGTH_SHORT).show();
                   // activity.fetchPrevious();
                } else {
                    Toast.makeText(activity.getApplicationContext(), "Left Swipe", Toast.LENGTH_SHORT).show();
                   // activity.fetchNext();
                }

                return true;
            } 

            return false;
        }

        @Override
        public void onLongPress(MotionEvent e) {
            // TODO Auto-generated method stub

    }

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { 
            // TODO Auto-generated method stub
            return false;
    }

        @Override
        public void onShowPress(MotionEvent e) {
            // TODO Auto-generated method stub

    }

       @Override
       public boolean onSingleTapUp(MotionEvent e) {
          // TODO Auto-generated method stub
           return false;
       }

       }

   }

Please try it!

like image 66
G_J Avatar answered Oct 16 '22 22:10

G_J