GestureDetector.SimpleOnGestureListener and GestureDetectorCompat don't work. What's wrong with my code?
Asked Answered
P

1

11

I'm following Detecting common gestures guide. I have linked to android-support-v4.jar library to get GestureDetectorCompat, and my code seems exactly the same as in the guide, except I'm detecting gestures in my custom view rather than in activity:

public class MyGlView extends GLSurfaceView {

    private GestureDetectorCompat m_gestureDetector = null;

    public MyGlView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }
    public MyGlView(Context context) {
        super(context);
        init(context);
    }
    private void init(Context context) {
        if (m_gestureDetector == null)
            m_gestureDetector = new GestureDetectorCompat(context, new MyGestureListener());

        setEGLContextClientVersion(2);
        setRenderer(new DrawSurfRenderer());
        setRenderMode(RENDERMODE_CONTINUOUSLY); 
    }

@Override
    public boolean onTouchEvent(MotionEvent event) {

        m_gestureDetector.onTouchEvent(event);      
        return super.onTouchEvent(event);
    }

public class MyGestureListener extends GestureDetector.SimpleOnGestureListener {

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
        {
            Log.e("", "OnScroll: deltaX=" + String.valueOf(e2.getX() - e1.getX()) + ", deltaY=" + String.valueOf(e2.getY() - e1.getY()));
            return true;
        }

        @Override
        public boolean onSingleTapUp(MotionEvent e)
        {
            Log.e("", "onSingleTapUp: X=" + String.valueOf(e.getX()) + ", Y=" + String.valueOf(e.getY()));
            return true;
        }

        @Override
        public void onLongPress(MotionEvent e)
        {
            Log.e("", "onLongPress: X=" + String.valueOf(e.getX()) + ", Y=" + String.valueOf(e.getY()));
        }
    }

No matter what I do with the touchscreen, I'm only getting onLongPress. In fact, when I do fast tap (quickly touching and releasing the screen) I still get onLongPress slightly after I remove my finger from the screen ( suspect that's a long tap detection delay).

What's the catch?

Pepsinogen answered 1/11, 2013 at 14:41 Comment(5)
did you try to change return super.onTouchEvent(event); to return false;? And try yours actions on the Simple View (such as WebView like example).Vastitude
@R.id.pandacoder: return false; doesn't change anything.Pepsinogen
After some investigation i think you can try to add onDown method which returns true to your onTouchEvent method.Vastitude
You will give always onLongPress because MotionEvent.ACTION_DOWN never processed\accesed on your gestureDetector. You always will give ACTION_UP. Why no ACTION_MOVE? Because in Android Action_Move precessed after he give Action_UP. So gesture detector will be processed your actions like a long press.Vastitude
@R.id.pandacoder: thank you! It seems silly that there is no default implementation, or that onDown is not abstract...Pepsinogen
H
22

I quote Android Guide on Detecting Common Gestures:

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.

The fact that you did not implement the onDown() method was causing side effects.

Huertas answered 21/3, 2014 at 7:36 Comment(1)
Weirdly enough I had the same problem as the OP, except that my onLongPress Method was called just fine, despite not having onDown return trueTheron

© 2022 - 2024 — McMap. All rights reserved.