Question

On a Samsung Galaxy Note 10.1 with Android 4.0.4 the GestureDetector does not fire OnGestureListener#onScroll when two fingers are placed on screen (it does for one finger). This works well on other devices. In my application I want to enable scrolling only when at least two fingers are involved.

This is the view implementation to reproduce the phenomena:

public class MyView extends View {

    GestureDetector scrollGestureDetector;

    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);

        scrollGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onScroll(final MotionEvent e1, final MotionEvent e2, final float distanceX, final float distanceY) {
                System.out.println("SCROLL " + distanceX + ", " + distanceY);
                return true;
            }
        });
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        scrollGestureDetector.onTouchEvent(event);
        return true;
    }
}

Is this behavior known/documented/wanted? Are there known workarounds?

Was it helpful?

Solution

You need to implement one more method onDown in your GestureDetector.SimpleOnGestureListener, like this:

scrollGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
        @Override
        public boolean onScroll(final MotionEvent e1, final MotionEvent e2, final float distanceX, final float distanceY) {
            System.out.println("SCROLL " + distanceX + ", " + distanceY);
            return true;
        }

        @Override
        public boolean onDown(MotionEvent e) {
            return true;
        }

    });

Because according to this document and this guide:

Notified when a tap occurs with the down MotionEvent that triggered it. This will be triggered immediately for every down event. All other events should be preceded by this.

And

Whether or not you use GestureDetector.OnGestureListener, it's best practice to implement an onDown() method that returns true. This is because all gestures begin with an onDown() message. If you return false from onDown(), as GestureDetector.SimpleOnGestureListener does by default, the system assumes that you want to ignore the rest of the gesture, and the other methods of GestureDetector.OnGestureListener never get called. This has the potential to cause unexpected problems in your app. The only time you should return false from onDown() is if you truly want to ignore an entire gesture.

You need to return true in onDown, so that onScroll will be triggered.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top