How to implemennt OnZoomListener on MapView

我是研究僧i 提交于 2019-11-28 23:44:46

I had to subclass MapView and override dispatchDraw

Here is the code:

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

This blog helped me a lot: http://pa.rezendi.com/2010/03/responding-to-zooms-and-pans-in.html

Above works great. Is there maybe simpler solution? I tried to implement onTouchListener on MapView directly but touch event would be detected only once if onTouchListener would return false. If it would return true, touch would be detected every time, but map zooming and panning wouldn't work.

I put all the code from above together and came up with this class:


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


}

And the corresponding listener interface:


package at.blockhaus.wheels.map;

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

Maybe a bit late, but have you tried with an OnOverlayGestureListener?

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

Edit: I believe what you've found is probably the only mechanism to allow this detection. (Editing my post to remove misinformation) Extending the MapView and overriding the onDraw() method would work. One consideration to make will be how often to fire the code listening to zoom. For instance, while zooming the onDraw may be called dozens of times each with a different zoom level. This may cause poor performance if your listener is firing every time. You could throttle this by determining that a zoom change has taken place and then waiting for the zoom level to be the same on two subsequent redraws before firing the event. This all depends on how you want your code to be called.

use dispatchTouch() method to detect touch events on the map and make sure you call the super() method to carry out the default map touch functions. (Setting onTouchListener will disable the in built events like zooming and panning if you return true from your functiion, and will handle touch only once if you return false.)

in dispatchTouch method, you can check for no of touch points by using event.getPointerCount(). use Action_UP to detect whether the user has zoomed out or not by calling mapview.getZoomLevel(); if you find the zoom level changed, you can carry out your actions.

i implemented it the following way, and it works for 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());
        }
    }

It worked for me!

Try via this method

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

                    @Override
                    public boolean onZoom(ZoomEvent event)
                        {

                            return false;
                        }
                });

MapView provides build-in zoom controls that support pinch. If it doesn't work out of the box you could try setting mapView.setBuiltInZoomControls(true); This way you should not need the OnZoomListener.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!