8

I have search for google map center while zooming using double tap and pinch to zoom. I have found one solution for Here, This is only for double Tap to zoom solution.

TouchableWrapper

 public class TouchableWrapper extends FrameLayout {

    GestureDetectorCompat mGestureDetector;


    public TouchableWrapper(Context context) {
        super(context);
        mGestureDetector = new GestureDetectorCompat(context, mGestureListener);
    }


    private final GestureDetector.SimpleOnGestureListener mGestureListener
            = new GestureDetector.SimpleOnGestureListener() {
        @Override
        public boolean onDoubleTap(MotionEvent e) {
            Log.e("GestureDetector", "Executed");
            //Notify the event bus (I am using Otto eventbus of course) that you have just received a double-tap event on the map, inside the event bus event listener
            EventBus_Singleton.getInstance().post(new EventBus_Poster("double_tapped_map"));

            return true;
        }
    };

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        mGestureDetector.onTouchEvent(ev);
        return super.onInterceptTouchEvent(ev);
    }


}

I have used Otto for event trigger.

public class EventBus_Singleton {

    private static final Bus BUS = new Bus();

    public static Bus getInstance() {
        return BUS;
    }

    public EventBus_Singleton() {
    }

    public void post(String s) {
        BUS.post(s);
    }
}

EventBus_Poster

public class EventBus_Poster {
    public final String string;

    EventBus_Poster(String string) {
        this.string = string;
    }
}

In My Map Activity I have used event Receiving method to zoom map on same location.

 @Subscribe
    public void EventBus_singleton(EventBus_Poster event) {
        Log.e("EventBus_singleton", "Executed");
        if (event != null && event.string.equals("double_tapped_map")) {
            if (mapFragment != null) {
                mapFragment.getMap().getUiSettings().setZoomGesturesEnabled(false);
                mapFragment.getMap().getUiSettings().setRotateGesturesEnabled(false);

                mapFragment.getMap().setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() {
                    @Override
                    public void onCameraChange(CameraPosition cameraPosition) {
                        LatLng lng = cameraPosition.target;
                        Log.e("LatLng", "" + lng);
                    }
                });
                mapFragment.getMap().animateCamera(CameraUpdateFactory.zoomIn(), 400, null);
            }

        }
    }

I have tried to use ScaleGestureDetector.SimpleOnScaleGestureListener to make pinch zoom but it didnt work and also sometime it is lagging. Can anyone help me to make pinch zoom in google map?

Community
  • 1
  • 1
Shvet
  • 1,159
  • 1
  • 18
  • 30

1 Answers1

7

Well, I've found that when trying to do this, a successful pinch-to-zoom involves both velocity and scale condition. Velocity is measured to determine whether you really want to zoom depending on how fast you moved the two fingers away from or closer to each other, you can try this inside Google Maps and inside Uber's app, you can actually keep moving the fingers away from or closer to each other but so slowly that you will not trigger a zoom in/out event on the map!

So definitely involves velocity when trying to determine a full pinch gesture. Second of course you need scale also, and I've printed out the scale value and it is always smaller than exactly 1.0 when you start pinching to zoom out and always larger than 1.0 when you start pinching to zoom in.

Combination of these two will definitely get you better results, see velocity first I'd say

private final ScaleGestureDetector.OnScaleGestureListener mScaleGestureListener
        = new ScaleGestureDetector.SimpleOnScaleGestureListener() {
    /**
     * This is the active focal point in terms of the viewport. Could be a local
     * variable but kept here to minimize per-frame allocations.
     */

    float startingSpan;
    float startFocusX;
    float startFocusY;

    @Override
    public boolean onScaleBegin(ScaleGestureDetector scaleGestureDetector) {
        startingSpan = scaleGestureDetector.getCurrentSpan();
        startFocusX = scaleGestureDetector.getFocusX();
        startFocusY = scaleGestureDetector.getFocusY();

        return true;
    }

    @Override
    public boolean onScale(ScaleGestureDetector scaleGestureDetector) {
        float scale = scaleGestureDetector.getCurrentSpan() / startingSpan;

        mVelocityTracker.computeCurrentVelocity(1000);

        Log.d("VELOCITY", "X vel : " + mVelocityTracker.getXVelocity());
        Log.d("VELOCITY", "Y vel : " + mVelocityTracker.getYVelocity());

        if (scale <= 1.0) {
            EventBus_Singleton.getInstance().post(new EventBus_Poster("pinched_map", "out"));
        } else {
            EventBus_Singleton.getInstance().post(new EventBus_Poster("pinched_map", "in"));
        }

        return true;
    }
};
Odaym
  • 1,896
  • 1
  • 20
  • 31
  • Solved for Shvet? or someone else accepted? let's know the results on your side? – Odaym Jul 17 '15 at 21:34
  • Yes, It is working for me as i needed, except some times it also drags map sometimes as i want user to drag it. – Shvet Jul 18 '15 at 05:45
  • what do you mean by drag? the action that happens when you put for example 1 finger and start dragging the map left right top down? or pan when you move the camera on the map up and down? – Odaym Jul 18 '15 at 23:17
  • It is zooming out after i take fingures away from screen – Shvet Jul 20 '15 at 10:31
  • It has Velocity zero always and there is no use of x velocity and y velocity. – Shvet Jul 20 '15 at 13:01
  • 1
    The way it is implemented now as you see in the above code with the logs set, is not 100% :) I should have mentioned that because I've stopped working on that project since I posted the above, sorry. But there is no doubt that there is a need to measure velocity, this just means I'm measuring it wrong – Odaym Jul 20 '15 at 13:36
  • Ok. But if i am not keeping it fast, map drags it is not steady. is there a way to make it static when i zoom it. – Shvet Jul 20 '15 at 13:55
  • And what should be done with the map for these in/out events? mapFragment.getMap().animateCamera(CameraUpdateFactory.zoomIn() - is not smooth – Yuliya Tarasenko Oct 05 '15 at 14:18
  • @YuliyaTarasenko honestly I do use zoomIn() as well and it is smooth, be sure to check if you are doing any heavy task (like checking for new address) every time you hit onCameraChange() listener, this will cause the cam to stutter as you move around – Odaym Oct 06 '15 at 12:57
  • @Odaym if we use zoomIn() it will zoom by 1 every time `onScale` is called which will make zoom in not smooth. It also zoom in even after i will take fingers away from screen. – Shvet Oct 10 '15 at 07:19
  • @Shvet did you disable zoomGestures on the native map? Can you verify that its your own onScale() that's being called and not the native onScale from the default gestureListener? – Odaym Oct 10 '15 at 12:20
  • @Odaym yes it is disabled and i have put Log which is showing that Framlayout's onGesture is being called. – Shvet Oct 12 '15 at 09:41
  • hey @agonist_ follow this to know: http://stackoverflow.com/questions/31353743/how-to-make-google-make-in-center-when-using-double-tap-and-pinch-to-zoom-in-and – Odaym Dec 23 '15 at 22:20