2010-02-24 14 views

Odpowiedz

0

Jedynym sposobem, jaki mogę wymyślić jest rozszerzenie MapView i nadpisanie OnTouchEvent i obserwowanie działania Up. Dzięki temu dowiesz się, że użytkownik zakończył pracę i możesz uzyskać zasięg lat/lon, aby określić region, który powinieneś sprawdzić.

+0

to nie działa, jeśli użytkownik rzuca mapę, ponieważ mapa ustąpi po akcji UP – Dori

4

try MapView-overlay-manager, to rozszerzenie dla wierzchnią dla Androida mapy,

ma jakąś uproszczoną OnGestureListener niewiele przykład:

onSingleTap(MotionEvent, ManagedOverlay, GeoPoint, OverlayItem) 

onDoubleTap(MotionEvent, ManagedOverlay, GeoPoint, OverlayItem) 

onLongPress(MotionEvent, ManagedOverlay, GeoPoint, OverlayItem) 

onZoom(ZoomEvent, ManagedOverlay) 

onScrolled(...) 

Link: http://code.google.com/p/mapview-overlay-manager/ nadzieję, że pomoże

1

Niestety, nie ma w tym wbudowanej funkcjonalności w narzędziach MapView (dziwne niedopatrzenie, ponieważ ta funkcjonalność dotyczy zestawu SDK JavaScript, a także SDK iOS).

Możesz sobie z tym poradzić dość łatwo, ale używając Runnable i po prostu odpytuj MapView. Robię to, śledząc "ostatni" stan:

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

A następnie porównując je z bieżącymi wartościami. Jeśli wartości uległy zmianie, wiesz, że widok mapy został przeniesiony. Jeśli nie, nie możesz nic zrobić.

W obu przypadkach prześlij program do uruchomienia w celu wykonania kolejnego uruchomienia po około 500 ms i powtórz proces. Możesz użyć onResume() i onPause(), aby usunąć wywołanie zwrotne dla Runnable i ponownie go uruchomić w razie potrzeby.

+1

"Niestety, nie ma w tym żadnej wbudowanej funkcji w narzędziach MapView", metoda onLayout radzi sobie z tym z wdziękiem, patrz moja odpowiedź na przykład. –

1

Klasa MapView może śledzić zmiany za pomocą metody onLayout.

tj

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

Testowanie na Gingerbread dla trzech interakcji mapowych (PAN z palcem, ZOOM za pomocą kontrolek, PINCH/REVERSE PINCH z dwoma palcami), oto co otrzymałem: 1) PAN: istnieje wiele zdarzeń onLayout ze zmienionymi = true 2) ZOOM: there jest jednym zdarzeniem ze zmienionym = true, wieloma zdarzeniami ze zmienionymi = false 3) PINCH/REVERSE PINCH: nie ma żadnych zdarzeń ze zmianą = true, wiele zdarzeń ze zmianą = false. Tak więc za pomocą tej metody można wykryć proste PAN z palcem/ZOOM poprzez zmiany sterowania, ale nie można wykryć zmian dokonanych za pomocą PINCH/REVERSE PINCH. – Theo

3

Można utworzyć SimpleMapView który rozciąga 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); 
    } 
} 

Masz Słuchaczy, możesz umieścić kod panoramy lub zoomu. Następnie w 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> 

A potem w kodzie można określić Pan Listener:

mapView.addPanChangeListener(new PanChangeListener() { 

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

stare pytanie, ale napisałem klasę jakiś czas temu o nazwie ExMapView który pożary zdarzenie po region mapy zaczyna się zmieniać (onRegionBeginChange) i kiedy przestaje się zmieniać (onRegionEndChange). Ta klasa jest do użytku ze starym MapView, a nie V2.0. Mam nadzieję, że to komuś pomaga.

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); 
    } 
} 
Powiązane problemy