繁体   English   中英

关于android上谷歌地图的缩放事件

[英]On zoom event for google maps on android

我们正在构建一个使用google maps api for android的应用程序。

我有我的MapController和MapView,我启用了内置的缩放控件:

mapView.setBuiltInZoomControls(true);

我现在想要在用户实际放大地图时获得一个事件,我该怎么做呢? 我找不到这样的事件或任何我可以检测到缩放级别变化的一般事件。

更新

不推荐使用mapView.getZoomControls() 文档建议使用mapView.setBuiltInZoomControls(bool)。 这没关系,但我根本无法弄清楚如何对内置缩放控件中的事件采取行动。

使用Google Maps Android API v2,您可以使用GoogleMap.OnCameraChangeListener,如下所示:

mMap.setOnCameraChangeListener(new OnCameraChangeListener() {

    private float currentZoom = -1;

    @Override
    public void onCameraChange(CameraPosition pos) {
        if (pos.zoom != currentZoom){
            currentZoom = pos.zoom;
            // do you action here
        }
    }
});

您可以实现自己的缩放值的基本“轮询”,以检测何时使用Android 处理程序更改了缩放。

使用以下代码进行runnable事件 这是您应该进行处理的地方。

private Handler handler = new Handler();

public static final int zoomCheckingDelay = 500; // in ms

private Runnable zoomChecker = new Runnable()
{
    public void run()
    {
        checkMapIcons();

        handler.removeCallbacks(zoomChecker); // remove the old callback
        handler.postDelayed(zoomChecker, zoomCheckingDelay); // register a new one
    }
};

使用启动回调事件

protected void onResume()
{
    super.onResume();
    handler.postDelayed(zoomChecker, zoomCheckingDelay);
}

当你离开活动时停止

protected void onPause()
{
    super.onPause();
    handler.removeCallbacks(zoomChecker); // stop the map from updating
}

如果你想要更长的写作, 这里的 文章可以在这里找到。

我使用这个有onZoom函数监听器的库。 http://code.google.com/p/mapview-overlay-manager/ 效果很好。

正如OP所说,使用onUserInteractionEvent并自己进行测试。

这是一个干净的解决方案。 只需将此TouchOverlay私有类添加到您的活动和一个名为onZoom的方法(由此内部类调用)。

请注意,您必须将此TouchOverlay添加到mapView中,例如

mapView.getOverlays().add(new TouchOverlay());

它会在用户触摸地图时跟踪缩放级别,例如双击或捏缩放,然后在缩放级别更改时触发onZoom方法(使用缩放级别)。

   private class TouchOverlay extends com.google.android.maps.Overlay {
            int lastZoomLevel = -1;

            @Override
            public boolean onTouchEvent(MotionEvent event, MapView mapview) {
                if (event.getAction() == 1) {
                    if (lastZoomLevel == -1)
                        lastZoomLevel = mapView.getZoomLevel();

                    if (mapView.getZoomLevel() != lastZoomLevel) {
                        onZoom(mapView.getZoomLevel());
                        lastZoomLevel = mapView.getZoomLevel();
                    }
                }
                return false;
            }
        }

        public void onZoom(int level) {
            reloadMapData(); //act on zoom level change event here
        }

android API建议您使用具有setOnZoomInClickListener()的ZoomControls

要添加这些缩放控件,您将:

ZoomControls mZoom = (ZoomControls) mapView.getZoomControls();

然后将mZoom添加到您的布局中。

您可以使用

ZoomButtonsController zoomButton = mapView.getZoomButtonsController();
zoomButton.setOnZoomListener(listener);

希望能帮助到你

我想这个问题可能还有另一个答案。 在任何缩放后调用Overlay类绘制方法,我相信在缩放级别更改后调用它。 您能否构建自己的应用程序以利用此功能? 如果你愿意,你甚至可以使用虚拟覆盖来检测它。 这比使用延迟的runnable更有效吗?

@Override
public boolean draw (Canvas canvas, MapView mapView, boolean shadow, long when) {
    int zoomLevel = mapView.getZoomLevel();
    // do what you want with the zoom level
    return super.draw(canvas, mapView, shadow, when);
}

对于V2.0之前的版本,我创建了一个扩展MapView的类,它在地图区域开始更改(onRegionBeginChange)并停止更改(onRegionEndChange)时向侦听器发出警报。

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;

public class ExMapView extends MapView {
    private static final String TAG = ExMapView.class.getSimpleName();
    private static final int DURATION_DEFAULT = 700;

    private OnRegionChangedListener onRegionChangedListener;
    private GeoPoint previousMapCenter;
    private int previousZoomLevel;
    private int changeDuration; // This is the duration between when the user stops moving the map around and when the onRegionEndChange event fires.
    private boolean isTouched = false;
    private boolean regionChanging = false;

    private Runnable onRegionEndChangeTask = new Runnable() {
        public void run() {
            regionChanging = false;
            previousMapCenter = getMapCenter();
            previousZoomLevel = getZoomLevel();
            if (onRegionChangedListener != null) {
                onRegionChangedListener.onRegionEndChange(ExMapView.this, previousMapCenter, previousZoomLevel);
            }
        }
    };

    public ExMapView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public ExMapView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    public ExMapView(Context context, String apiKey) {
        super(context, apiKey);
        init();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        isTouched = event.getAction() != MotionEvent.ACTION_UP;
        return super.onTouchEvent(event);
    }

    @Override
    public void computeScroll() {
        super.computeScroll();

        // If the map region is still changing (user is still scrolling or zooming), reset timer for onRegionEndChange.
        if ((!isTouched && !getMapCenter().equals(previousMapCenter)) || (previousZoomLevel != getZoomLevel())) {

            // If the region has just begun changing, fire off onRegionBeginChange event.
            if (!regionChanging) {
                regionChanging = true;
                if (onRegionChangedListener != null) {
                    onRegionChangedListener.onRegionBeginChange(this, previousMapCenter, previousZoomLevel);
                }
            }

            // Reset timer for onRegionEndChange.
            removeCallbacks(onRegionEndChangeTask);
            postDelayed(onRegionEndChangeTask, changeDuration);
        }
    }

    private void init() {
        changeDuration = DURATION_DEFAULT;
        previousMapCenter = getMapCenter();
        previousZoomLevel = getZoomLevel();
    }

    public void setOnRegionChangedListener(OnRegionChangedListener listener) {
        onRegionChangedListener = listener;
    }

    public void setChangeDuration(int duration) {
        changeDuration = duration;
    }

    public interface OnRegionChangedListener {
        public abstract void onRegionBeginChange(ExMapView exMapView, GeoPoint geoPoint, int zoomLevel);
        public abstract void onRegionEndChange(ExMapView exMapView, GeoPoint geoPoint, int zoomLevel);
    }
}

你可以像这样使用Zoom CControl。

在这里,我附上代码,你可以如何实现zoomcontrol。

1 >> XML文件应该是这样的。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent">

    <com.google.android.maps.MapView 
        android:id="@+id/mapView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:enabled="true"
        android:clickable="true"
        android:apiKey="0l4sCTTyRmXTNo7k8DREHvEaLar2UmHGwnhZVHQ"
        />

    <LinearLayout android:id="@+id/zoom" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:layout_alignParentBottom="true" 
        android:layout_centerHorizontal="true" 
        /> 

</RelativeLayout>

2 >>关于你在oncreate方法里面的主要活动做下面的事情。 在这里,您使用mapView充气您的视图

mapView = (MapView) findViewById(R.id.mapView);
        LinearLayout zoomLayout = (LinearLayout)findViewById(R.id.zoom);  
        View zoomView = mapView.getZoomControls(); 

        zoomLayout.addView(zoomView, 
            new LinearLayout.LayoutParams(
                LayoutParams.WRAP_CONTENT, 
                LayoutParams.WRAP_CONTENT)); 
        mapView.displayZoomControls(true);

.................................................. .........这就是你如何使用API​​的内置变焦控制..

你可以拥有自己的自定义代码来实现放大和缩小这样的...

public boolean onKeyDown(int keyCode, KeyEvent event) 
{
    MapController mc = mapView.getController(); 
    switch (keyCode) 
    {
        case KeyEvent.KEYCODE_3:
            mc.zoomIn();
            break;
        case KeyEvent.KEYCODE_1:
            mc.zoomOut();
            break;
    }
    return super.onKeyDown(keyCode, event);
}    

..这就是我实施的方式......

Thanks..Rakesh

我用了上面的混合物。 我发现使用timmer每半秒启动一个线程会导致地图变得非常怪异。 可能是因为我每次都使用几个If语句。 所以我从onUserInteraction开始延迟500ms的线程。 这给了zoomLevel在线程开始运行之前更新的足够时间,从而获得正确的zoomlevel而不需要每隔500ms运行一次线程。

public void onUserInteraction() {
    handler.postDelayed(zoomChecker, zoomCheckingDelay);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM