2010-02-24 26 views

Trả lời

0

Cách duy nhất tôi có thể nghĩ là mở rộng MapView và ghi đè lên OnTouchEvent và xem cho hành động Lên. Điều này sẽ cho bạn biết rằng người dùng đã hoàn tất việc di chuyển và bạn có thể nhận được khoảng thời gian lat/lon để xác định khu vực bạn nên xem.

+0

điều này không hoạt động nếu người dùng vứt bản đồ vì bản đồ sẽ giải quyết sau hành động UP – Dori

4

thử MapView-overlay-manager, nó là một phần mở rộng cho overlayer cho các bản đồ android,

nó có một số đơn giản hóa OnGestureListener, vài ví dụ:

onSingleTap(MotionEvent, ManagedOverlay, GeoPoint, OverlayItem) 

onDoubleTap(MotionEvent, ManagedOverlay, GeoPoint, OverlayItem) 

onLongPress(MotionEvent, ManagedOverlay, GeoPoint, OverlayItem) 

onZoom(ZoomEvent, ManagedOverlay) 

onScrolled(...) 

liên kết: http://code.google.com/p/mapview-overlay-manager/ hy vọng nó sẽ giúp

1

Đáng buồn thay, không có chức năng tích hợp để thực hiện việc này trong các công cụ MapView (một sự giám sát lạ vì chức năng này nằm trong SDK JavaScript, cũng như SDK iOS).

Bạn có thể giải quyết vấn đề này một cách dễ dàng mặc dù bằng cách sử dụng Runnable và chỉ cần bỏ phiếu MapView. Tôi thực hiện việc này bằng cách theo dõi trạng thái "cuối cùng":

getLatitudeSpan(); 
getLongitudeSpan(); 
getCenter(); 
getZoomLevel(); 

Và sau đó so sánh chúng với giá trị hiện tại. Nếu các giá trị thay đổi, bạn biết chế độ xem bản đồ đã di chuyển. Nếu không, bạn không thể làm gì cả.

Dù bằng cách nào, hãy lên lịch lại thời gian chạy cho lần chạy khác sau 500ms hoặc lâu hơn và lặp lại quy trình. Bạn có thể sử dụng onResume() và onPause() để loại bỏ các cuộc gọi lại cho Runnable và khởi động lại nó khi cần thiết.

+1

"Đáng buồn thay, không có chức năng tích hợp để thực hiện việc này trong các công cụ MapView", phương thức onLayout xử lý điều này khá duyên dáng, xem câu trả lời của tôi cho một ví dụ. –

1

Lớp MapView có thể theo dõi các thay đổi bằng phương pháp onLayout.

ví dụ:

class CustomMapView extends MapView { 

    protected void onLayout(boolean changed,int left, int right, int top, int bottom){ 
     super.onLayout(changed,left, right, top, bottom); 
     if(changed){ 
     // do something special 
     } 
    } 
} 
+2

Thử nghiệm trên Gingerbread cho ba tương tác bản đồ (PAN bằng ngón tay, ZOOM qua điều khiển, PINCH/PINM đảo ngược bằng hai ngón tay), đây là những gì tôi nhận được: 1) PAN: có nhiều sự kiện onLayout với thay đổi = true 2) ZOOM: ở đó là một sự kiện có thay đổi = true, nhiều sự kiện với changed = false 3) PINCH/REVERSE PINCH: không có sự kiện nào được thay đổi = true, nhiều sự kiện với changed = false. Vì vậy, bằng cách sử dụng phương pháp này bạn có thể phát hiện PAN đơn giản với ngón tay/ZOOM thông qua các thay đổi điều khiển, nhưng bạn không thể phát hiện thay đổi được thực hiện với PINCH/REVERSE PINCH. – Theo

3

Bạn có thể tạo một SimpleMapView kéo dài MapView.

public class SimpleMapView extends MapView { 

    private int currentZoomLevel = -1; 
    private GeoPoint currentCenter; 
    private List<ZoomChangeListener> zoomEvents = new ArrayList<ZoomChangeListener>(); 
    private List<PanChangeListener> panEvents = new ArrayList<PanChangeListener>(); 

    public SimpleMapView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
    } 

    public SimpleMapView(Context context, String apiKey) { 
     super(context, apiKey); 
    } 

    public SimpleMapView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 
    /** 
    * 
    * @return 
    */ 
    public int[][] getBounds() { 

     GeoPoint center = getMapCenter(); 
     int latitudeSpan = getLatitudeSpan(); 
     int longtitudeSpan = getLongitudeSpan(); 
     int[][] bounds = new int[2][2]; 

     bounds[0][0] = center.getLatitudeE6() - (latitudeSpan/2); 
     bounds[0][1] = center.getLongitudeE6() - (longtitudeSpan/2); 

     bounds[1][0] = center.getLatitudeE6() + (latitudeSpan/2); 
     bounds[1][1] = center.getLongitudeE6() + (longtitudeSpan/2); 
     return bounds; 
    } 

    public boolean onTouchEvent(MotionEvent ev) { 
     if (ev.getAction() == MotionEvent.ACTION_UP) { 
      GeoPoint centerGeoPoint = this.getMapCenter(); 
      if (currentCenter == null || 
        (currentCenter.getLatitudeE6() != centerGeoPoint.getLatitudeE6()) || 
        (currentCenter.getLongitudeE6() != centerGeoPoint.getLongitudeE6())) { 
       firePanEvent(currentCenter, this.getMapCenter()); 
      } 
      currentCenter = this.getMapCenter(); 
     } 
     return super.onTouchEvent(ev); 
    } 

    @Override 
    protected void dispatchDraw(Canvas canvas) { 
     super.dispatchDraw(canvas); 
     if(getZoomLevel() != currentZoomLevel){ 
      fireZoomLevel(currentZoomLevel, getZoomLevel()); 
      currentZoomLevel = getZoomLevel(); 
     } 
    } 

    @Override 
    public void setSatellite(boolean on){ 
     super.setSatellite(on); 
    } 

    @Override 
    public MapController getController(){ 
     return super.getController(); 
    } 

    private void fireZoomLevel(int old, int current){ 
     for(ZoomChangeListener event : zoomEvents){ 
      event.onZoom(old, current); 
     } 
    } 

    private void firePanEvent(GeoPoint old, GeoPoint current){ 
     for(PanChangeListener event : panEvents){ 
      event.onPan(old, current); 
     } 
    } 

    public void addZoomChangeListener(ZoomChangeListener listener){ 
     this.zoomEvents.add(listener); 
    } 

    public void addPanChangeListener(PanChangeListener listener){ 
     this.panEvents.add(listener); 
    } 
} 

Bạn có Người nghe bạn có thể đặt mã để xoay hoặc thu phóng. Sau đó, trong xml của bạn:

<com.androidnatic.maps.SimpleMapView android:clickable="true" 
        android:layout_height="match_parent" android:id="@+id/mapView" 
        android:layout_width="match_parent" 
        android:apiKey="xxx"> 
</com.androidnatic.maps.SimpleMapView> 

Và sau đó trong mã của bạn, bạn có thể chỉ định Pan Thính giả:

mapView.addPanChangeListener(new PanChangeListener() { 

      @Override 
      public void onPan(GeoPoint old, GeoPoint current) { 
          //TODO 
         } 
     }); 
0

Cũ câu hỏi, nhưng tôi đã viết một lớp học một thời gian lại gọi ExMapView mà cháy một sự kiện khi vùng bản đồ bắt đầu thay đổi (onRegionBeginChange) và khi nó ngừng thay đổi (onRegionEndChange). Lớp này là để sử dụng với MapView cũ, không phải là V2.0. Hy vọng nó sẽ giúp ai đó.

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 ExMapView extends MapView { 
    private static final String TAG = ExMapView.class.getSimpleName(); 
    private static final int DURATION_DEFAULT = 700; 

    private OnRegionChangedListener onRegionChangedListener; 
    private GeoPoint previousMapCenter; 
    private int previousZoomLevel; 
    private int changeDuration; // This is the duration between when the user stops moving the map around and when the onRegionEndChange event fires. 
    private boolean isTouched = false; 
    private boolean regionChanging = false; 

    private Runnable onRegionEndChangeTask = new Runnable() { 
     public void run() { 
      regionChanging = false; 
      previousMapCenter = getMapCenter(); 
      previousZoomLevel = getZoomLevel(); 
      if (onRegionChangedListener != null) { 
       onRegionChangedListener.onRegionEndChange(ExMapView.this, previousMapCenter, previousZoomLevel); 
      } 
     } 
    }; 

    public ExMapView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     init(); 
    } 

    public ExMapView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
     init(); 
    } 

    public ExMapView(Context context, String apiKey) { 
     super(context, apiKey); 
     init(); 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     isTouched = event.getAction() != MotionEvent.ACTION_UP; 
     return super.onTouchEvent(event); 
    } 

    @Override 
    public void computeScroll() { 
     super.computeScroll(); 

     // If the map region is still changing (user is still scrolling or zooming), reset timer for onRegionEndChange. 
     if ((!isTouched && !getMapCenter().equals(previousMapCenter)) || (previousZoomLevel != getZoomLevel())) { 

      // If the region has just begun changing, fire off onRegionBeginChange event. 
      if (!regionChanging) { 
       regionChanging = true; 
       if (onRegionChangedListener != null) { 
        onRegionChangedListener.onRegionBeginChange(this, previousMapCenter, previousZoomLevel); 
       } 
      } 

      // Reset timer for onRegionEndChange. 
      removeCallbacks(onRegionEndChangeTask); 
      postDelayed(onRegionEndChangeTask, changeDuration); 
     } 
    } 

    private void init() { 
     changeDuration = DURATION_DEFAULT; 
     previousMapCenter = getMapCenter(); 
     previousZoomLevel = getZoomLevel(); 
    } 

    public void setOnRegionChangedListener(OnRegionChangedListener listener) { 
     onRegionChangedListener = listener; 
    } 

    public void setChangeDuration(int duration) { 
     changeDuration = duration; 
    } 

    public interface OnRegionChangedListener { 
     public abstract void onRegionBeginChange(ExMapView exMapView, GeoPoint geoPoint, int zoomLevel); 
     public abstract void onRegionEndChange(ExMapView exMapView, GeoPoint geoPoint, int zoomLevel); 
    } 
} 
Các vấn đề liên quan