可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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);
回答1:
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.
回答2:
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();
}
回答3:
Maybe a bit late, but have you tried with an OnOverlayGestureListener?
http://code.google.com/p/mapview-overlay-manager/wiki/OnOverlayGestureListener
回答4:
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.
回答5:
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.
回答6:
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!
回答7:
Try via this method
map.setMapListener(new MapListener()
{
....
@Override
public boolean onZoom(ZoomEvent event)
{
return false;
}
});
回答8:
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.