Как реализовать OnZoomListener на MapView

Я хотел бы иметь onZoomListener на своем MapView. Код ниже - это то, что я сделал. Он регистрирует нажатие кнопок масштабирования. Поскольку все новые телефоны теперь поддерживают масштабирование, это бесполезно. Кто-нибудь знает, как сделать реальный onZoomListener? Спасибо.

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

person bobetko    schedule 18.01.2011    source источник


Ответы (8)


Мне пришлось создать подкласс MapView и переопределить dispatchDraw

Вот код:

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

Мне очень помог этот блог: http://pa.rezendi.com/2010/03/responding-to-zooms-and-pans-in.html

Выше работает отлично. Может есть более простое решение? Я попытался реализовать onTouchListener напрямую в MapView, но событие касания будет обнаружено только один раз, если onTouchListener вернет false. Если бы он возвращал true, прикосновение определялось бы каждый раз, но масштабирование и панорамирование карты не работали бы.

person bobetko    schedule 18.01.2011

Я собрал весь код выше вместе и придумал этот класс:


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;

public interface OnPanAndZoomListener {
    public void onPan();
    public void onZoom();
}

person vinzenzweber    schedule 06.03.2011

Может быть, немного поздно, но вы пробовали с OnOverlayGestureListener?

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

person Cliff    schedule 10.04.2011

Попробуйте этим методом

map.setMapListener(new MapListener()
                {
                    ....

                    @Override
                    public boolean onZoom(ZoomEvent event)
                        {

                            return false;
                        }
                });
person Axrorxo'ja Yodgorov    schedule 16.03.2017

Редактировать: я считаю, что то, что вы нашли, вероятно, является единственным механизмом, позволяющим это обнаружение. (Редактирование моего сообщения для удаления дезинформации) Расширение MapView и переопределение метода onDraw() будут работать. Одним из соображений, которые следует учитывать, будет то, как часто запускать код, прослушивающий масштабирование. Например, при масштабировании onDraw может вызываться десятки раз, каждый раз с разным уровнем масштабирования. Это может привести к снижению производительности, если ваш слушатель срабатывает каждый раз. Вы можете ограничить это, определив, что произошло изменение масштаба, а затем подождав, пока уровень масштабирования не станет одинаковым при двух последующих перерисовках, прежде чем запускать событие. Все зависит от того, как вы хотите, чтобы ваш код вызывался.

person Nick Campion    schedule 18.01.2011

используйте метод dispatchTouch() для обнаружения событий касания на карте и убедитесь, что вы вызываете метод super() для выполнения функций касания карты по умолчанию. (Настройка onTouchListener отключит встроенные события, такие как масштабирование и панорамирование, если вы вернете true из своей функции, и будет обрабатывать касание только один раз, если вы вернете false.)

в методе dispatchTouch вы можете проверить отсутствие точек касания, используя event.getPointerCount(). используйте Action_UP, чтобы определить, уменьшил ли пользователь масштаб или нет, вызвав mapview.getZoomLevel(); если вы обнаружите, что уровень масштабирования изменился, вы можете выполнять свои действия.

person rDroid    schedule 24.07.2011

я реализовал это следующим образом, и он работает для одного/мультитача:

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

Это сработало для меня!

person rDroid    schedule 06.10.2011

MapView предоставляет встроенные элементы управления масштабированием, которые поддерживают масштабирование. Если это не работает из коробки, вы можете попробовать установить mapView.setBuiltInZoomControls(true); Таким образом, вам не нужен OnZoomListener.

person ShadowMare    schedule 18.01.2011
comment
У меня нет проблем с отображением управления масштабированием. Мне нужно вызвать событие, когда происходит масштабирование. - person bobetko; 19.01.2011