Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android googlemaps V2 - Disable scroll on pan or zoom

I would like to disable scroll on Android googlemaps when the user is zooming. In IOS google maps, its kind of easy, just set a parameter: self.settings.allowScrollGesturesDuringRotateOrZoom = NO; Unfortunately, I have not found this kind of feature in Android and Im looking for solutions. The best idea I have right now is to extend the googlemaps view, intercept the touch on the view and if the touch action is pinch then set the zoom manually. Now this seems to me quite hacky and unreliable. Is there a better way to do this? Any other suggestions or ideas? I do not have any code yet about that, so cant include any of it here.

For some context why this needs to be done, is that there is a pin in the centre which is used to mark the exact center of the map and the center LatLng is used for geocoding addresses.

like image 639
splangi Avatar asked Aug 12 '15 06:08

splangi


2 Answers

EDIT

There is an official way now of doing this and it is marked now as the correct answer.

OLD ANSWER

I ended up doing a completely custom solution, although because of ScaleGestureDetector bug it will work only API > 16. Will post updates if this I will find a solution to that. Right now I use regular Mapview with scale gestures endbled on API <= 16 and API > 16 I use my custom class:

    public class CustomEventMapView extends MapView {

    private int fingers = 0;
    private GoogleMap googleMap;
    private long lastZoomTime = 0;
    private float lastSpan = -1;
    private Handler handler = new Handler();

    private ScaleGestureDetector gestureDetector;

    public CustomEventMapView(Context context, GoogleMapOptions options) {
        super(context, options);
    }

    public CustomEventMapView(Context context) {
        super(context);
    }

    @Override
    public void getMapAsync(final OnMapReadyCallback callback) {
        super.getMapAsync(new OnMapReadyCallback() {
            @Override
            public void onMapReady(final GoogleMap googleMap) {
                gestureDetector = new ScaleGestureDetector(getContext(), new ScaleGestureDetector.OnScaleGestureListener() {
                    @Override
                    public boolean onScale(ScaleGestureDetector detector) {
                        if (lastSpan == -1) {
                            lastSpan = detector.getCurrentSpan();
                        } else if (detector.getEventTime() - lastZoomTime >= 50) {
                            lastZoomTime = detector.getEventTime();
                            googleMap.animateCamera(CameraUpdateFactory.zoomBy(getZoomValue(detector.getCurrentSpan(), lastSpan)), 50, null);
                            lastSpan = detector.getCurrentSpan();
                        }
                        return false;
                    }

                    @Override
                    public boolean onScaleBegin(ScaleGestureDetector detector) {
                        lastSpan = -1;
                        return true;
                    }

                    @Override
                    public void onScaleEnd(ScaleGestureDetector detector) {
                        lastSpan = -1;

                    }
                });
                CustomEventMapView.this.googleMap = googleMap;
                callback.onMapReady(googleMap);
            }
        });
    }

    private float getZoomValue(float currentSpan, float lastSpan) {
        double value = (Math.log(currentSpan / lastSpan) / Math.log(1.55d));
        return (float) value;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {

        switch (ev.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_POINTER_DOWN:
                fingers = fingers + 1;
                break;
            case MotionEvent.ACTION_POINTER_UP:
                fingers = fingers - 1;
                break;
            case MotionEvent.ACTION_UP:
                fingers = 0;
                break;
            case MotionEvent.ACTION_DOWN:
                fingers = 1;
                break;
        }
        if (fingers > 1) {
            disableScrolling();
        } else if (fingers < 1) {
            enableScrolling();
        }
        if (fingers > 1) {
            return gestureDetector.onTouchEvent(ev);
        } else {
            return super.dispatchTouchEvent(ev);
        }
    }

    private void enableScrolling() {
        if (googleMap != null && !googleMap.getUiSettings().isScrollGesturesEnabled()) {
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    googleMap.getUiSettings().setAllGesturesEnabled(true);
                }
            }, 50);
        }
    }

    private void disableScrolling() {
        handler.removeCallbacksAndMessages(null);
        if (googleMap != null && googleMap.getUiSettings().isScrollGesturesEnabled()) {
            googleMap.getUiSettings().setAllGesturesEnabled(false);
        }
    }
}
like image 144
splangi Avatar answered Oct 03 '22 20:10

splangi


This is an old question but I had the same issue. After some googling I found this solution (which I think is the proper one): Have your activity implement onMapReadyCallback and then in your overridden onMapReady set the googleMap.getUiSettings().setScrollGesturesEnabledDuringRotateOrZoom(false); That made the trick for me.

public class MainActivity extends AppCompatActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener{
        GoogleMap gMap;
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        gMap = googleMap;
        gMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
        gMap.getUiSettings().setZoomControlsEnabled(true);
        gMap.getUiSettings().setZoomGesturesEnabled(true);
        gMap.getUiSettings().setCompassEnabled(false);
        gMap.getUiSettings().setScrollGesturesEnabled(false);
        gMap.getUiSettings().setScrollGesturesEnabledDuringRotateOrZoom(false);
        gMap.setMyLocationEnabled(false);
        gMap.animateCamera(CameraUpdateFactory.zoomTo(8f));
    }
like image 43
Tomas F. Avatar answered Oct 03 '22 19:10

Tomas F.