Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ScaleGestureDetector.OnScaleGestureListener.onScaleEnd() method not being hit

Update: I figured out what is happening. See comments.

I am trying to write a ViewSwitcher that passes all gestures to its first child until it receives a scale gesture; it then passes them to its second child until that child is zoomed out again completely, when it reverts to the first child. My subclass has a ScaleGestureDetector and I made a very simple listener:

    protected class OnScaleModeSwitcher implements ScaleGestureDetector.OnScaleGestureListener
    {
        protected PageFlipSwitcher owner;

        public OnScaleModeSwitcher(PageFlipSwitcher newOwner)
        {
            super();
            owner = newOwner;
        }

        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            return false;
        }

        @Override
        public boolean onScaleBegin(ScaleGestureDetector detector) {
            owner.onScaleBegin();
//returning false here causes the rest of the gesture to be ignored.
            return false;
        }

        @Override
        public void onScaleEnd(ScaleGestureDetector detector) {
            owner.onScaleEnd();
        }
    }

As you can see all it does is take a reference to the owner object on construction, then pass some events to methods within the owner class. However, onScaleEnd() is not being reached by the code.

I'm aware that onInterceptTouchEvent can be a little dicey; I followed the suggestions in the Android docs for it as closely as possible and have

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev)
    {
        onTouchEvent(ev);
        return false;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev)
    {
//mode is the name of the ScaleGestureDetector
        mode.onTouchEvent(ev);

//this code just passes events to the children
//it seems to work OK
        if(zoomActive)
        {
            //ZoomSwitcher
            getChildAt(1).onTouchEvent(ev);
        }
        else
        {
            //Gallery
            getChildAt(0).onTouchEvent(ev);
        }
        return true;
    }

I read somewhere else that a GestureDetector may not receive the ACTION_UP event:

Android: How to detect when a scroll has ended

Is that what is happening here? If so what is the point of the onScaleEnd() method?

EDIT:

I have worked this out: it is because my methods return false. Eclipse auto-implemented some stubs and I didn't change the return values when I filled them in.

like image 702
Andrew Wyld Avatar asked Jul 06 '11 10:07

Andrew Wyld


1 Answers

If a ScaleGestureDetector is set up that returns false from onScaleBegin(...), none of the subsequent methods will be hit. Generally methods that consume a MotionEvent but return false do not get subsequent MotionEvents until after ACTION_UP, when the listeners are reset.

like image 141
Andrew Wyld Avatar answered Dec 14 '22 14:12

Andrew Wyld