【问题标题】:Android googlemaps V2 - Disable scroll on pan or zoomAndroid googlemaps V2 - 禁用平移或缩放滚动
【发布时间】:2015-11-04 15:23:05
【问题描述】:

我想在用户缩放时禁用 Android googlemaps 上的滚动。在IOS谷歌地图中,​​很简单,只需设置一个参数:self.settings.allowScrollGesturesDuringRotateOrZoom = NO; 不幸的是,我还没有在 Android 中找到这种功能,我正在寻找解决方案。我现在最好的想法是扩展 googlemaps 视图,拦截视图上的触摸,如果触摸动作是捏合,则手动设置缩放。现在这在我看来相当老套和不可靠。有一个更好的方法吗?还有其他建议或想法吗?我还没有任何代码,所以不能在这里包含任何代码。

在某些情况下,为什么需要这样做,因为中心有一个大头针,用于标记地图的确切中心,而中心 LatLng 用于对地址进行地理编码。

【问题讨论】:

标签: android google-maps


【解决方案1】:

编辑

现在有一种官方方法可以做到这一点,现在它被标记为正确答案。

老答案

我最终做了一个完全自定义的解决方案,尽管由于 ScaleGestureDetector 错误,它仅适用于 API > 16。如果我会找到解决方案,我会发布更新。现在我在 API 16 上使用带有缩放手势的常规 Mapview 我使用我的自定义类:

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

【讨论】:

  • Math.log(1.55d) 是什么意思?以及所有的缩放计算(Math.log(currentSpan / lastSpan) / Math.log(1.55d))?
  • 当用户用两根手指持续触摸地图时,disableScrolling()方法会被连续调用。如何阻止它来电?因为,它使相机空闲侦听器被调用。但是,我需要在相机空闲监听器中做一些操作。由于disableScrolling方法不断被调用,导致camera idle listener中的操作发生了多次。
【解决方案2】:

这是一个老问题,但我遇到了同样的问题。经过一番谷歌搜索后,我找到了这个解决方案(我认为这是正确的): 让您的活动实现 onMapReadyCallback,然后在您覆盖的 onMapReady 中设置 googleMap.getUiSettings().setScrollGesturesEnabledDuringRotateOrZoom(false); 这对我来说是个窍门。

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

【讨论】:

  • 不适合我!
【解决方案3】:

您需要做的就是将map:uiScrollGesturesmap:uiZoomGestures 分配为false

map:uiScrollGestures="false"

map:uiZoomGestures="false"

【讨论】:

  • 我想允许滚动和缩放,但我想禁止在缩放期间滚动。这将完全禁用滚动和缩放手势。
猜你喜欢
  • 2017-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-09
  • 2013-02-05
相关资源
最近更新 更多