2010-01-06 23 views
37

我們正在構建一個應用程序,它正在使用Android的谷歌地圖API。對谷歌地圖上的變焦事件android

我有我的MapController和MapView的,我內置的縮放控件使用啓用:

mapView.setBuiltInZoomControls(true); 

我現在想,當用戶在地圖上居然縮放得到一個事件,我怎麼去關於那個?我無法找到此類事件或任何可以檢測到縮放級別變化的普通事件。

更新

The mapView.getZoomControls() is deprecated。而文檔建議使用mapView.setBuiltInZoomControls(bool)代替。這沒關係,但我根本無法弄清楚如何根據內置的縮放控件來處理事件。

+3

我試着實現onUserInteraction事件,出於同樣的目的,但我仍然有問題。我正在顯示需要根據縮放級別縮放的圖像,所以顯然我想在用戶縮放時調用其redraw()方法。我的問題是,當用戶點擊縮放按鈕時,會調用onUserInteraction,因此zoomLevel尚未更新,只有在更新zoomLevel的下一次交互(單擊,跨度,其他)時纔會更新。所以,我的圖像只有在實際縮放後的交互後纔會更新。有任何想法嗎? – Itsik 2010-06-12 23:50:09

+1

這個問題和答案指的是API v1,我在下面爲誰正在使用[Google Maps Android API v2](https://developers.google。com/maps/documentation/android /) – tarmelop 2013-02-23 23:10:04

回答

37

隨着谷歌地圖的Android API第2版,您可以使用一個GoogleMap.OnCameraChangeListener這樣的:

mMap.setOnCameraChangeListener(new OnCameraChangeListener() { 

    private float currentZoom = -1; 

    @Override 
    public void onCameraChange(CameraPosition pos) { 
     if (pos.zoom != currentZoom){ 
      currentZoom = pos.zoom; 
      // do you action here 
     } 
    } 
}); 
+3

'setOnCameraChangeListener()'現在已被棄用 – 2017-10-09 12:57:48

4

android API建議您使用ZoomControls具有setOnZoomInClickListener()

要添加這些縮放控制您可以:

ZoomControls mZoom = (ZoomControls) mapView.getZoomControls(); 

,然後添加到mZoom佈局。

+0

感謝您的回答。所述MapView.getZoomControls()已過時,與使用MapView.setBuiltInZoomControls(boolean)方法的建議。但我找不到任何地方從這些內置的縮放控件中獲取任何事件。編號:http://code.google.com/android/add-ons/google-apis/reference/com/google/android/maps/MapView.html#getZoomControls()。 – 2010-01-06 14:58:05

+0

我明白了。那麼它看起來像有一個無證mapView.getZoomButtonsController(),您可以使用,在http://code.google.com/p/android/issues/detail?id=3348描述,否則你就得使用mapview.onkeydown並測試縮放。 – JasonOfEarth 2010-01-06 15:20:31

+0

我得到了我想要使用onUserInteraction事件,並手動測試在變焦水平的變化。這對於通知用戶放大來查看我的覆蓋物的必要性而言非常有用。 – 2010-01-06 17:37:16

5

正如OP所說,使用onUserInteractionEvent並自己做測試。

+3

'onUserInteractionEvent()'在縮放級別更改之前調用*。這實際上意味着,對於每個縮放事件,監視縮放的應用程序正在運行一個事件。 – 2011-03-16 11:41:55

+0

@保羅:嗨。本來我並沒有考慮這個,但看起來你是對的,我所展示的敬酒總是一個落後。 – 2011-03-18 10:35:06

+1

您可以創建一個'Handler'實例,並通過像'postDelayed定期檢查縮放級別的變化(新的Runnable(){...},500)',但我真的不喜歡這樣的解決方案。 – 2011-03-18 16:45:00

4

可以使用

ZoomButtonsController zoomButton = mapView.getZoomButtonsController(); 
zoomButton.setOnZoomListener(listener); 

希望它有助於

+2

這非常具體地回答了OP的問題,但僅通過變焦按鈕引發縮放事件的事件。捏,例如,不會調用偵聽器的回調。 – 2011-03-23 08:06:39

2

U可以有放大CControl這樣。

在這裏,我附上代碼如何實現縮放控制。

1 >> XML文件應該是這樣的。

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"> 

    <com.google.android.maps.MapView 
     android:id="@+id/mapView" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     android:enabled="true" 
     android:clickable="true" 
     android:apiKey="0l4sCTTyRmXTNo7k8DREHvEaLar2UmHGwnhZVHQ" 
     /> 

    <LinearLayout android:id="@+id/zoom" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentBottom="true" 
     android:layout_centerHorizontal="true" 
     /> 

</RelativeLayout> 

2 >>在你的主要活動裏面創建方法做下列事情。 這裏你用的MapView

mapView = (MapView) findViewById(R.id.mapView); 
     LinearLayout zoomLayout = (LinearLayout)findViewById(R.id.zoom); 
     View zoomView = mapView.getZoomControls(); 

     zoomLayout.addView(zoomView, 
      new LinearLayout.LayoutParams(
       LayoutParams.WRAP_CONTENT, 
       LayoutParams.WRAP_CONTENT)); 
     mapView.displayZoomControls(true); 

充氣視圖.................................. ......................... 這是如何使用API​​的內置縮放控制..

您可以擁有自己的自定義代碼實現放大和縮小這樣的...

public boolean onKeyDown(int keyCode, KeyEvent event) 
{ 
    MapController mc = mapView.getController(); 
    switch (keyCode) 
    { 
     case KeyEvent.KEYCODE_3: 
      mc.zoomIn(); 
      break; 
     case KeyEvent.KEYCODE_1: 
      mc.zoomOut(); 
      break; 
    } 
    return super.onKeyDown(keyCode, event); 
}  

..This是如何我已經實現...

Thanks..Rakesh

25

您可以使用android Handler實現您自己的縮放值的基本「輪詢」,以檢測變焦何時更改。

對於您的可運行事件使用以下代碼。這是你的處理應該完成的地方。

private Handler handler = new Handler(); 

public static final int zoomCheckingDelay = 500; // in ms 

private Runnable zoomChecker = new Runnable() 
{ 
    public void run() 
    { 
     checkMapIcons(); 

     handler.removeCallbacks(zoomChecker); // remove the old callback 
     handler.postDelayed(zoomChecker, zoomCheckingDelay); // register a new one 
    } 
}; 

開始使用

​​

停止它,當你離開這個是基於可利用

protected void onPause() 
{ 
    super.onPause(); 
    handler.removeCallbacks(zoomChecker); // stop the map from updating 
} 

活性的回調事件如果你想要更長時間,找到here寫上去。

+1

我已經獲得了懸賞這個答案,因爲這是確定地圖是否已被移動或縮放的最簡單的方法。 – 2011-03-23 08:03:55

1

我使用了上述的混合物。我發現使用timmer每半秒啓動一個線程會導致地圖變得非常糟糕。可能是因爲我每次都使用一些If語句。所以我從onUserInteraction開始延遲500ms的線程。這爲線程開始運行之前zoomLevel提供了足夠的時間來更新,因此無需每500ms運行一次線程即可獲得正確的縮放級別。

public void onUserInteraction() { 
    handler.postDelayed(zoomChecker, zoomCheckingDelay); 
} 
3

我想這個問題可能會有另一個答案。覆蓋類繪製方法在任何縮放後調用,我相信這是在縮放級別更改後調用的。你能不能架構你的應用程序來利用這個優勢?如果你願意的話,你甚至可以使用虛擬覆蓋來檢測這個。這會比使用帶有延遲的runnable更有效嗎?

@Override 
public boolean draw (Canvas canvas, MapView mapView, boolean shadow, long when) { 
    int zoomLevel = mapView.getZoomLevel(); 
    // do what you want with the zoom level 
    return super.draw(canvas, mapView, shadow, when); 
} 
4

這是一個乾淨的解決方案。只需將此TouchOverlay私有類添加到您的活動以及稱爲onZoom的方法(由此內部類調用)即可。

請注意,您必須將此TouchOverlay添加到您的地圖視圖。

mapView.getOverlays().add(new TouchOverlay()); 

每當用戶觸摸地圖時,它都會跟蹤縮放級別,例如,雙擊或縮放縮放,然後在縮放級別改變時觸發onZoom方法(使用縮放級別)。

private class TouchOverlay extends com.google.android.maps.Overlay { 
      int lastZoomLevel = -1; 

      @Override 
      public boolean onTouchEvent(MotionEvent event, MapView mapview) { 
       if (event.getAction() == 1) { 
        if (lastZoomLevel == -1) 
         lastZoomLevel = mapView.getZoomLevel(); 

        if (mapView.getZoomLevel() != lastZoomLevel) { 
         onZoom(mapView.getZoomLevel()); 
         lastZoomLevel = mapView.getZoomLevel(); 
        } 
       } 
       return false; 
      } 
     } 

     public void onZoom(int level) { 
      reloadMapData(); //act on zoom level change event here 
     } 
+0

使用您的解決方案,我能夠輕鬆捕捉縮放變化! Thx – 2012-09-12 18:53:02

+0

輝煌的解決方案,但它沒有檢測到變焦的第一個變化。刪除第一個if語句爲-1解決了這個問題。 – Aelexe 2012-11-04 10:48:44

2

對於預V2.0,我做了延伸的MapView,提醒與事件當聽衆類地圖區域開始改變(onRegionBeginChange)並停止改變(onRegionEndChange)。

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