8
votes

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?

1
are you looking to stop scrolling? then you can use UiSettings.setScrollGesturesEnabled(false).sachithkn
I want map to stay in center when i zoom it, in normal when we zoom it it will drag away.Shvet
At least comment if you downvote the question and give good reason for it.Shvet
Have you question resolved on this post?bjiang
@bjiang It is done partially. I need to implement pinch to zoom too.Shvet

1 Answers

7
votes

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;
    }
};