在Android上的谷歌地图缩放事件
我们正在build立一个应用程序,使用Android的谷歌地图API。
我有我的MapController和MapView,并启用内置的缩放控制使用:
mapView.setBuiltInZoomControls(true);
我现在想在用户实际放大地图的时候得到一个事件,我该怎么做呢? 我可以find没有这样的事件或任何一般事件,我可以检测到缩放级别的变化。
更新
mapView.getZoomControls()已被弃用 。 而文档build议使用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 处理程序更改缩放的时间。
对于可运行事件使用以下代码。 这是你的处理应该完成的地方。
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 } };
使用开始callback事件
protected void onResume() { super.onResume(); handler.postDelayed(zoomChecker, zoomCheckingDelay); }
并在您离开活动时停止
protected void onPause() { super.onPause(); handler.removeCallbacks(zoomChecker); // stop the map from updating }
文章这是基于可以在这里find,如果你想更长的时间写。
我使用这个库有一个onZoom函数监听器。 http://code.google.com/p/mapview-overlay-manager/ 。 效果很好。
正如OP所说,使用onUserInteractionEvent并自己做testing。
Android APIbuild议你使用ZoomControls ,它有一个setOnZoomInClickListener()
要添加这些缩放控件,您将:
ZoomControls mZoom = (ZoomControls) mapView.getZoomControls();
然后将mZoom添加到您的布局。
这是一个干净的解决scheme。 只需将此TouchOverlay私有类添加到您的活动以及一个名为onZoom(由此内部类调用)的方法即可。
请注意,您必须将此TouchOverlay添加到您的地图视图中
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 }
您可以使用
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); }
你可以像这样使用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 >>在你的主要活动里面创build方法做以下的事情。 在这里你正在用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
对于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); } }
我用了上述的混合物。 我发现使用timmer每半秒钟启动一个线程会导致地图变得非常糟糕。 可能是因为我每次都使用一些If语句。 所以我从onUserInteraction开始延迟500ms的线程。 这给了zoomLevel足够的时间来在线程开始运行之前更新,从而得到正确的缩放级别,而不需要每500ms运行一次线程。
public void onUserInteraction() { handler.postDelayed(zoomChecker, zoomCheckingDelay); }