2010-02-24 11 views
19

मैं एक एंड्रॉइड ऐप बना रहा हूं जो मैप व्यू के दृश्य क्षेत्र के आधार पर वस्तुओं की खोज करता है। क्या नक्शा पॅन किया गया है या ज़ूम किया गया है यह जानने के लिए मेरे MapView पर श्रोता सेट अप करने का कोई तरीका है?मैं कैसे पता लगा सकता हूं कि एक एंड्रॉइड मैप व्यू को प्रतिबंधित या ज़ूम किया गया है या नहीं?

+0

क्या आपके पास इसका एक उदाहरण है? –

उत्तर

0

मैप व्यू को विस्तारित करने और ऑन टचवेन्ट को ओवरराइड करने और ऊपर की कार्रवाई के लिए देखने का एकमात्र तरीका है। यह आपको बताएगा कि उपयोगकर्ता आगे बढ़ना समाप्त कर चुका है और आप जिस क्षेत्र को चेक आउट करना चाहते हैं उसे निर्धारित करने के लिए आप लेट/लोन अवधि प्राप्त कर सकते हैं।

+0

यदि उपयोगकर्ता मानचित्र के रूप में मानचित्र को उतारता है तो यह काम नहीं करता है, यूपी एक्शन – Dori

4

कोशिश MapView ओवरले प्रबंधक, यह एंड्रॉयड नक्शे के लिए overlayer के लिए एक विस्तार है,

यह कुछ सरलीकृत 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 टूल में ऐसा करने के लिए कोई अंतर्निहित कार्यक्षमता नहीं है (यह कार्यक्षमता जावास्क्रिप्ट एसडीके के साथ-साथ आईओएस एसडीके में एक अजीब निरीक्षण है)।

आप आसानी से इस से निपट सकते हैं हालांकि रननेबल का उपयोग करके और केवल MapView मतदान कर सकते हैं। मैं इसे "अंतिम" स्थिति का ट्रैक रखकर करता हूं:

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

और फिर उन्हें वर्तमान मानों की तुलना करना। यदि बदले गए मान, तो आप जानते हैं कि मानचित्र दृश्य स्थानांतरित हो गया है। यदि नहीं, तो आप कुछ भी नहीं कर सकते हैं।

किसी भी तरह से, 500ms या उसके बाद किसी अन्य रन के लिए रननेबल को पुन: निर्धारित करें और प्रक्रिया दोहराएं। आप रननेबल के लिए कॉलबैक को निकालने के लिए रेज़्यूम() और ऑन पॉज़() पर उपयोग कर सकते हैं और इसे आवश्यकतानुसार पुनरारंभ करें।

+1

"अफसोस की बात है, मैप व्यू टूल्स में ऐसा करने के लिए कोई अंतर्निहित कार्यक्षमता नहीं है" नहीं, ऑनलाइट विधि यह बहुत सुंदर तरीके से संभालती है, देखें एक उदाहरण के लिए मेरा जवाब। –

1

MapView क्लास ऑनआउट विधि का उपयोग कर परिवर्तनों को ट्रैक कर सकता है।

अर्थात

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

तीन नक्शा इंटरैक्शन के लिए जिंजरब्रेड पर परीक्षण (उंगली के साथ पैन, नियंत्रण के माध्यम से ज़ूम, पिनच/दो उंगलियों के साथ रिवर पिनच), यह मुझे मिला है: 1) पैन: बदले गए = सही 2 के साथ कई ऑनआउट घटनाएं हैं) ज़ूम: वहां बदले गए = सत्य के साथ एक घटना है, बदली = झूठी 3 के साथ कई घटनाएं) पिनच/रिवर्स पिनच: बदले गए = सत्य के साथ कोई घटना नहीं है, बदली = झूठी के साथ कई घटनाएं हैं। तो इस विधि का उपयोग करके आप नियंत्रण पैन के माध्यम से उंगली/ज़ूम के साथ सरल पैन का पता लगा सकते हैं, लेकिन आप पिनच/रीवर पिनच के साथ किए गए परिवर्तन का पता नहीं लगा सकते हैं। – Theo

3

आप एक SimpleMapView कि 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); 
    } 
} 

आपके पास श्रोताओं हैं जो आप पैन या ज़ूम के लिए कोड डाल सकते हैं। फिर अपने एक्सएमएल में:

<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 के साथ उपयोग के लिए है, वी 2.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); 
    } 
} 
संबंधित मुद्दे

 संबंधित मुद्दे