2010-02-24 56 views

回答

0

我能想到的唯一方法是擴展MapView並覆蓋OnTouchEvent並觀察Up操作。這會告訴你用戶已經完成移動,你可以得到經緯度來確定你應該簽出的區域。

+0

這是行不通的,因爲地圖將在UP操作後解決。 – Dori 2012-10-30 18:00:35

4

試MapView的疊加經理,這是一個擴展覆蓋層爲Android地圖,

它有一些簡化OnGestureListener,幾個例子:

onSingleTap(MotionEvent, ManagedOverlay, GeoPoint, OverlayItem) 

onDoubleTap(MotionEvent, ManagedOverlay, GeoPoint, OverlayItem) 

onLongPress(MotionEvent, ManagedOverlay, GeoPoint, OverlayItem) 

onZoom(ZoomEvent, ManagedOverlay) 

onScrolled(...) 

鏈接:http://code.google.com/p/mapview-overlay-manager/希望它有助於

1

不幸的是,在MapView工具中沒有內置的功能(這是一個奇怪的疏忽,因爲這個功能在JavaScript SDK以及iOS SDK中)。

雖然使用Runnable並且只是輪詢MapView,但您可以輕鬆應對。我通過跟蹤「最後」狀態來執行此操作:

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

然後將它們與當前值進行比較。如果值已更改,則知道地圖視圖已移動。如果沒有,你什麼都不能做。

無論採用哪種方式,在500ms左右之後重新安排另一次運行的runnable並重復此過程。您可以使用onResume()和onPause()來刪除Runnable的回調,並根據需要重新啓動它。

+1

「令人遺憾的是,在MapView工具中沒有內置的功能來執行此操作」nope,onLayout方法非常優雅地處理這個問題,請參閱我的答案是一個例子。 – 2011-10-12 20:19:49

1

MapView類可以使用onLayout方法跟蹤更改。

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

在薑餅上測試三個地圖交互(PAN用手指,通過控件縮放,用兩根手指拖動PINCH/REVERSE PINCH),這就是我得到的結果:1)PAN:有多個onLayout事件,其中changed = true 2)ZOOM:有是更改= true的一個事件,更改= false的多個事件3)PINCH/REVERSE PINCH:沒有更改= true的事件,更改= false的多個事件。因此,使用這種方法,您可以通過控制變化來檢測簡單的PAN手指/ ZOOM,但您無法檢測到使用PINCH/REVERSE PINCH所做的更改。 – Theo 2011-10-31 19:39:15

3

您可以創建擴展MapView的一個SimpleMapView。

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

你有聽衆,你可以把代碼放在平移或縮放。 然後在您的xml:

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

然後在你的代碼,你可以指定潘監聽器:

mapView.addPanChangeListener(new PanChangeListener() { 

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

老問題,但我寫了一個類,而回叫ExMapView其觸發一個事件時,地圖區域開始變化(onRegionBeginChange)並停止變化(onRegionEndChange)。該類適用於舊版MapView,不適用於V2.0。希望它能幫助別人。

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); 
    } 
} 
相關問題