如何捕捉地图平移和缩放真的完成了?

我正试图编写一个应用程序,它将dynamic加载数据映射,而用户平移或缩放它。

我需要跟踪地图何时完成以更改其视图状态(停止平移或缩放),然后加载创build标记的新数据部分。 但实际上Google Maps API没有任何事件来处理这个问题。

有一些方法可以创build一个空的覆盖来控制onTouch事件等等,但是在用户完成触摸之后,地图平移可能会持续很长时间,因为GMaps使用某种惯性来平滑平移。

我试图MapView但其draw()方法是final因此它不能被覆盖。

任何想法如何精确处理平移和缩放整理?

Solutions Collecting From Web of "如何捕捉地图平移和缩放真的完成了?"

研究小时和一些决定被发现。 它有一些利弊,我会进一步描述。

我们应该做的主要事情是重写一些MapView的方法来处理它的绘图行为。 如果我们不能重写draw()方法,我们应该find另一种方法。还有一个来自View的衍生物,可以被重写 – computeScroll()方法。 它被重复调用,因为地图继续填充。 我们所要做的就是设置一些时间阈值来捕获computeScroll这个时候不再被调用。
这是我做的:

 import java.util.Timer; import java.util.TimerTask; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import com.google.android.maps.GeoPoint; import com.google.android.maps.MapView; public class EnhancedMapView extends MapView { public interface OnZoomChangeListener { public void onZoomChange(MapView view, int newZoom, int oldZoom); } public interface OnPanChangeListener { public void onPanChange(MapView view, GeoPoint newCenter, GeoPoint oldCenter); } private EnhancedMapView _this; // Set this variable to your preferred timeout private long events_timeout = 500L; private boolean is_touched = false; private GeoPoint last_center_pos; private int last_zoom; private Timer zoom_event_delay_timer = new Timer(); private Timer pan_event_delay_timer = new Timer(); private EnhancedMapView.OnZoomChangeListener zoom_change_listener; private EnhancedMapView.OnPanChangeListener pan_change_listener; public EnhancedMapView(Context context, String apiKey) { super(context, apiKey); _this = this; last_center_pos = this.getMapCenter(); last_zoom = this.getZoomLevel(); } public EnhancedMapView(Context context, AttributeSet attrs) { super(context, attrs); } public EnhancedMapView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public void setOnZoomChangeListener(EnhancedMapView.OnZoomChangeListener l) { zoom_change_listener = l; } public void setOnPanChangeListener(EnhancedMapView.OnPanChangeListener l) { pan_change_listener = l; } @Override public boolean onTouchEvent(MotionEvent ev) { if (ev.getAction() == 1) { is_touched = false; } else { is_touched = true; } return super.onTouchEvent(ev); } @Override public void computeScroll() { super.computeScroll(); if (getZoomLevel() != last_zoom) { // if computeScroll called before timer counts down we should drop it and start it over again zoom_event_delay_timer.cancel(); zoom_event_delay_timer = new Timer(); zoom_event_delay_timer.schedule(new TimerTask() { @Override public void run() { zoom_change_listener.onZoomChange(_this, getZoomLevel(), last_zoom); last_zoom = getZoomLevel(); } }, events_timeout); } // Send event only when map's center has changed and user stopped touching the screen if (!last_center_pos.equals(getMapCenter()) || !is_touched) { pan_event_delay_timer.cancel(); pan_event_delay_timer = new Timer(); pan_event_delay_timer.schedule(new TimerTask() { @Override public void run() { pan_change_listener.onPanChange(_this, getMapCenter(), last_center_pos); last_center_pos = getMapCenter(); } }, events_timeout); } } } 

那么你应该像这样在你的MapActivity中注册事件处理器:

 public class YourMapActivity extends MapActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mv = new EnhancedMapView(this, "<your Maps API key here>"); mv.setClickable(true); mv.setBuiltInZoomControls(true); mv.setOnZoomChangeListener(new EnhancedMapView.OnZoomChangeListener() { @Override public void onZoomChange(MapView view, int newZoom, int oldZoom) { Log.d("test", "zoom changed from " + oldZoom + " to " + newZoom); } } mv.setOnPanChangeListener(new EnhancedMapView.OnPanChangeListener() { public void onPanChange(MapView view, GeoPoint newCenter, GeoPoint oldCenter) { Log.d("test", "center changed from " + oldCenter.getLatitudeE6() + "," + oldCenter.getLongitudeE6() + " to " + newCenter.getLatitudeE6() + "," + newCenter.getLongitudeE6()); } } } 

那么这种方法的优点和缺点呢?
优点:
– 事件处理地图被平移或缩放。 触摸事件,使用的硬件键,甚至以编程方式触发的事件都被处理(如setZoom()或animate()方法)。
– 如果用户快速点击缩放button几次,可跳过不必要的数据加载。 事件只会在点击停止后才会触发。
缺点:
– 取消缩放或平移动作是不可能的(也许我会在将来添加这个function)

希望这个小class能帮助你。

MapChange项目最初在这里发表的类似问题帮助我完成了你所要求的同样的任务。