Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OnGestureListener#onScroll not being called from GestureDetector on Samsung Galaxy Note 10.1

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?

like image 713
Lars Blumberg Avatar asked Nov 29 '13 13:11

Lars Blumberg


People also ask

What is onShowPress?

onShowPress The user has performed a down MotionEvent and not performed a move or up yet. This event is commonly used to provide visual feedback to the user to let them know that their action has been recognized i.e. highlight an element.

What does the GestureDetector Ongesturelistener interface do when implemented?

GestureDetector. SimpleOnGestureListener provides an implementation for all of the on<TouchEvent> methods by returning false for all of them. Thus you can override only the methods you care about.

What is onFling?

onFling: is that the user lifts his finger in the end of the movement (that is the reason for what onFling is called one time). onScroll: is the general process of moving the viewport (that is, the 'window' of content you're looking at).

What is a gesture detector?

Android provides the GestureDetector class for detecting common gestures. Some of the gestures it supports include onDown() , onLongPress() , onFling() , and so on. You can use GestureDetector in conjunction with the onTouchEvent() method described above.


1 Answers

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.

like image 107
Wesley Avatar answered Sep 28 '22 06:09

Wesley