Событие масштабирования для карт google на Android

Мы создаем приложение, использующее Google Maps api для 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.

Использование следующего кода для вашего запускаемого события . Здесь ваша обработка должна быть выполнена.

 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 и выполните тест самостоятельно.

API android предлагает вам использовать ZoomControls, который имеет setOnZoomInClickListener ()

Чтобы добавить эти элементы управления масштабированием, вы должны:

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

Затем добавьте mZoom в свой макет.

Вот чистое решение. Просто добавьте этот частный класс 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 } 

Вы можете использовать

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

U может иметь 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.

У вас может быть собственный код для реализации Zoom In And Zoom, как это …

 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

Для pre-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 для запуска потока каждые полсекунды приводит к тому, что карта будет действительно jenky. Наверное, потому, что я каждый раз использовал пару статусов If. Поэтому я начал поток на задержку сообщения 500 мс от onUserInteraction. Это дает достаточно времени для обновления zoomLevel до того, как поток начнет работать, тем самым получив правильный масштабный уровень без запуска потока каждые 500 мс.

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