我正在尝试编写一个应用程序,将在用户平移或放大时动态加载数据进行映射.
我需要跟踪地图何时完成以更改其视图状态(停止平移或缩放),然后加载用于创建标记的新部分数据.但事实上,Google Maps API没有任何事件来处理这个问题.
有一些方法,例如创建一个空的覆盖以控制onTouch事件等等,但是在用户完成他的触摸之后,地图平移可以持续很长时间,因为GMaps使用某种惯性使平移更平滑.
我试图子类化MapView,但是它的draw()方法是final,因此它不能被覆盖.
任何想法如何精确处理平移和缩放整理?
解决方法
发现了一些研究时间和一些决定.它有一些缺点和职业,我将进一步描述.
我们应该做的主要事情是覆盖一些MapView的方法来处理它的绘图行为.如果我们不能覆盖draw()方法,我们应该找到另一种方法.另外一个派生从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 oldZoom) {
- Log.d("test","zoom changed from " + oldZoom + " to " + newZoom);
- }
- }
- mv.setOnPanChangeListener(new EnhancedMapView.OnPanChangeListener() {
- public void onPanChange(MapView view,GeoPoint oldCenter) {
- Log.d("test","center changed from " + oldCenter.getLatitudeE6() + "," + oldCenter.getLongitudeE6() + " to " + newCenter.getLatitudeE6() + "," + newCenter.getLongitudeE6());
- }
- }
- }
那么这种方法的优点和缺点呢?
优点:
– 事件处理任一方式地图被平移或缩放.触摸事件,使用的硬件键,甚至编程触发的事件都被处理(如setZoom()或animate()方法).
– 如果用户快速点击缩放按钮,可以跳过不必要的数据加载.点击停止后,事件将触发.
缺点:
– 很不可能取消放大或平移动作(也许我会在将来添加这个能力)
希望这个小班会帮你.