Cómo implementar OnZoomListener en MapView

Me gustaría tener onZoomListener en mi MapView. El código de abajo es lo que he hecho. Se registra si se pulsan los botones de zoom. Dado que todos los teléfonos nuevos soporta pinch to zoom, esto es inútil. ¿Alguien tiene idea de cómo hacer onZoomListener real? Gracias.

OnZoomListener listener = new OnZoomListener() { @Override public void onVisibilityChanged(boolean arg0) { // TODO Auto-generated method stub } @Override public void onZoom(boolean arg0) { Log.d(TAG, "ZOOM CHANGED"); // TODO Auto-generated method stub } }; ZoomButtonsController zoomButton = mapView.getZoomButtonsController(); zoomButton.setOnZoomListener(listener); 

Tuve que subclase MapView y reemplazar dispatchDraw

Aquí está el código:

  int oldZoomLevel=-1; @Override public void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); if (getZoomLevel() != oldZoomLevel) { Log.d(TAG, "ZOOOMED"); oldZoomLevel = getZoomLevel(); } } 

Este blog me ha ayudado mucho: http://pa.rezendi.com/2010/03/responding-to-zooms-and-pans-in.html

Arriba funciona muy bien. ¿Hay quizá solución más simple? Intenté implementar onTouchListener en MapView directamente, pero el evento touch sería detectado sólo una vez si onTouchListener devolvería false. Si devuelve true, el toque se detectará cada vez, pero el zoom y el desplazamiento del mapa no funcionarán.

Puse todo el código de arriba juntos y subí con esta clase:

package at.blockhaus.wheels.map; import android.content.Context; import android.graphics.Canvas; import android.util.AttributeSet; import android.view.MotionEvent; import com.google.android.maps.GeoPoint; import com.google.android.maps.MapView; public class CustomMapView extends MapView { private int oldZoomLevel = -1; private GeoPoint oldCenterGeoPoint; private OnPanAndZoomListener mListener; public CustomMapView(Context context, String apiKey) { super(context, apiKey); } public CustomMapView(Context context, AttributeSet attrs) { super(context, attrs); } public CustomMapView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public void setOnPanListener(OnPanAndZoomListener listener) { mListener = listener; } @Override public boolean onTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_UP) { GeoPoint centerGeoPoint = this.getMapCenter(); if (oldCenterGeoPoint == null || (oldCenterGeoPoint.getLatitudeE6() != centerGeoPoint.getLatitudeE6()) || (oldCenterGeoPoint.getLongitudeE6() != centerGeoPoint.getLongitudeE6()) ) { mListener.onPan(); } oldCenterGeoPoint = this.getMapCenter(); } return super.onTouchEvent(ev); } @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); if (getZoomLevel() != oldZoomLevel) { mListener.onZoom(); oldZoomLevel = getZoomLevel(); } } }
package at.blockhaus.wheels.map; import android.content.Context; import android.graphics.Canvas; import android.util.AttributeSet; import android.view.MotionEvent; import com.google.android.maps.GeoPoint; import com.google.android.maps.MapView; public class CustomMapView extends MapView { private int oldZoomLevel = -1; private GeoPoint oldCenterGeoPoint; private OnPanAndZoomListener mListener; public CustomMapView(Context context, String apiKey) { super(context, apiKey); } public CustomMapView(Context context, AttributeSet attrs) { super(context, attrs); } public CustomMapView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public void setOnPanListener(OnPanAndZoomListener listener) { mListener = listener; } @Override public boolean onTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.ACTION_UP) { GeoPoint centerGeoPoint = this.getMapCenter(); if (oldCenterGeoPoint == null || (oldCenterGeoPoint.getLatitudeE6() != centerGeoPoint.getLatitudeE6()) || (oldCenterGeoPoint.getLongitudeE6() != centerGeoPoint.getLongitudeE6()) ) { mListener.onPan(); } oldCenterGeoPoint = this.getMapCenter(); } return super.onTouchEvent(ev); } @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); if (getZoomLevel() != oldZoomLevel) { mListener.onZoom(); oldZoomLevel = getZoomLevel(); } } } 

Y la interfaz de escucha correspondiente:

package at.blockhaus.wheels.map; public interface OnPanAndZoomListener { public void onPan(); public void onZoom(); }
package at.blockhaus.wheels.map; public interface OnPanAndZoomListener { public void onPan(); public void onZoom(); } 

Tal vez un poco tarde, pero ¿has probado con un OnOverlayGestureListener?

http://code.google.com/p/mapview-overlay-manager/wiki/OnOverlayGestureListener

Edit: Creo que lo que has encontrado es probablemente el único mecanismo para permitir esta detección. (Editar mi mensaje para eliminar la información errónea) Extender el MapView y sobreescribir el método onDraw () funcionaría. Una consideración a hacer será la frecuencia con la que se dispara el código de escuchar zoom. Por ejemplo, mientras se hace zoom, el onDraw se puede llamar docenas de veces cada uno con un nivel de zoom diferente. Esto puede causar un rendimiento deficiente si su oyente está disparando cada vez. Usted podría acelerar esto determinando que un cambio del zumbido ha ocurrido y entonces esperar el nivel del zumbido ser igual en dos redraws subsecuentes antes de encender el acontecimiento. Todo esto depende de cómo quiera que se llame su código.

Utilice el método dispatchTouch () para detectar eventos táctiles en el mapa y asegúrese de llamar al método super () para llevar a cabo las funciones táctiles predeterminadas del mapa. (Establecer onTouchListener desactivará los eventos incorporados como el zoom y el panorámico si devuelve true de su función y manejará el tacto sólo una vez si devuelve false.)

En el método dispatchTouch, puede comprobar si hay puntos de contacto mediante event.getPointerCount (). Utilice Action_UP para detectar si el usuario ha ampliado o no el zoom llamando a mapview.getZoomLevel (); Si encuentra el nivel de zoom cambiado, puede realizar sus acciones.

I implementado de la siguiente manera, y funciona para single / multitouch:

 @Override protected void dispatchDraw(Canvas canvas) { // TODO Auto-generated method stub super.dispatchDraw(canvas); if (oldZoomLevel == -1) { oldZoomLevel = getZoomLevel(); } if (oldZoomLevel < getZoomLevel()) { System.out.println("zoomed in"); if (mOnZoomInListener != null) { mOnZoomInListener .onZoomedIn(this, oldZoomLevel, getZoomLevel()); } } if (oldZoomLevel > getZoomLevel()) { System.out.println("zoomed out"); if (mOnZoomOutListener != null) { mOnZoomOutListener.onZoomedOut(this, oldZoomLevel, getZoomLevel()); } } 

Funcionó para mí!

Prueba a través de este método

 map.setMapListener(new MapListener() { .... @Override public boolean onZoom(ZoomEvent event) { return false; } }); 

MapView proporciona controles de zoom incorporados que admiten pinch. Si no funciona fuera de la caja puede intentar establecer mapView.setBuiltInZoomControls(true); De esta manera usted no debe necesitar el OnZoomListener.

  • Cómo eliminar los botones de zoom en la vista web de Android?
  • Pinch Ampliar la vista web
  • ¿Cómo puedo implementar zoom en la Biblioteca Fresco?
  • Zoom automático en Google Maps en java? (Dependiendo de la resolución de pantalla de Android)
  • Lienzo Zoom va al punto (0,0)
  • ¿Cómo hacer que mi ImageView se pueda ampliar?
  • Cómo habilitar la función de zoom in / out (dos dedos) para una imagen en android
  • Android imageView: configuración de los parámetros de arrastrar y comprimir el zoom
  • Android google maps no se puede ampliar con compás activo
  • Marcadores de mapa de escala por Zoom, Android
  • Android: ¿Cómo puedo configurar el nivel de zoom de la vista del mapa en un radio de 1 km alrededor de mi ubicación actual?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.