如何在 MapView 上实现 OnZoomListener

发布于 2024-10-12 15:39:18 字数 561 浏览 7 评论 0原文

我想在我的 MapView 上有 onZoomListener 。 下面的代码是我所做的。如果点击缩放按钮,它会进行记录。由于现在所有新手机都支持捏合缩放,所以这是没有用的。有人知道如何做真正的 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);

I would like to have onZoomListener on my MapView.
The code below is what I have done. It registers if zoom buttons are tapped. Since all new phones now supports pinch to zoom, this is useless. Does anybody have idea how to do real onZoomListener? Thanks.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

萧瑟寒风 2024-10-19 15:39:18

我必须继承 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

以上效果很好。有没有更简单的解决方案?
我尝试直接在 MapView 上实现 onTouchListener,但是如果 onTouchListener 返回 false,则触摸事件只会被检测到一次。如果它返回 true,则每次都会检测到触摸,但地图缩放和平移将不起作用。

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.

跨年 2024-10-19 15:39:18

我将上面的所有代码放在一起并提出了这个类:


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

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

盛夏已如深秋| 2024-10-19 15:39:18

也许有点晚了,但是您尝试过使用 OnOverlayGestureListener 吗?

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

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

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

时光暖心i 2024-10-19 15:39:18

通过这个方法尝试一下

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

                    @Override
                    public boolean onZoom(ZoomEvent event)
                        {

                            return false;
                        }
                });

Try via this method

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

                    @Override
                    public boolean onZoom(ZoomEvent event)
                        {

                            return false;
                        }
                });
£冰雨忧蓝° 2024-10-19 15:39:18

编辑:我相信您所发现的可能是允许这种检测的唯一机制。 (编辑我的帖子以删除错误信息)扩展 MapView 并覆盖 onDraw() 方法是可行的。需要考虑的一个因素是触发监听 Zoom 的代码的频率。例如,在缩放时,onDraw 可能会被调用数十次,每次都有不同的缩放级别。如果您的侦听器每次都触发,这可能会导致性能不佳。您可以通过确定已发生缩放更改,然后在触发事件之前等待后续两次重绘中的缩放级别相同来限制此操作。这一切都取决于您希望如何调用代码。

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.

游魂 2024-10-19 15:39:18

使用dispatchTouch()方法来检测地图上的触摸事件,并确保调用super()方法来执行默认的地图触摸功能。 (如果从函数返回 true,设置 onTouchListener 将禁用缩放和平移等内置事件,如果返回 false,则仅处理一次触摸。)

在dispatchTouch方法中,您可以使用 event.getPointerCount 检查是否有触摸点()。使用Action_UP通过调用mapview.getZoomLevel()来检测用户是否缩小了;如果您发现缩放级别发生变化,您可以执行您的操作。

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.

仙女山的月亮 2024-10-19 15:39:18

我按照以下方式实现了它,它适用于单点/多点触控:

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

它对我有用!

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!

苦行僧 2024-10-19 15:39:18

MapView 提供支持捏合的内置缩放控件。
如果它不能开箱即用,您可以尝试设置 mapView.setBuiltInZoomControls(true);
这样您就不需要 OnZoomListener。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文