一個跟地圖有關的 App, 沒有地圖上的標記也是很奇怪的。所以,接下來我們要在地圖上加兩種標記。
首先我們要加上 Google Map API 提供的 MyLocationOverlay。
在 Main Activity 中宣告一個變數
private MyLocationOverlay m_MyLocationOverlay;
在 onCreate 函式裡,產生這個 Overlay,並且加入到 Map View 中。
m_MyLocationOverlay = new MyLocationOverlay(this, m_MapView);
m_MapView.getOverlays().add(m_MyLocationOverlay);
/*m_MyLocationOverlay.runOnFirstFix(new Runnable() {
public void run() {
m_MapView.getController().animateTo(m_MyLocationOverlay.getMyLocation());
}
});*/
有一段程式碼註解起來了,這段程式碼的用意在,當我們取得 Location 後,把 Map View 上的地圖,搬移到我們所在的位置上。但是因為我們在 GeoUpdateListener 中也有相同的功能,所以,這段程式碼其實可有可無。
接著,在 Main Activity 上,我們覆寫兩個函式。
@Override
protected void onResume() {
super.onResume();
m_MyLocationOverlay.enableMyLocation();
m_MyLocationOverlay.enableCompass();
}
@Override
protected void onPause() {
super.onPause();
m_MyLocationOverlay.disableMyLocation();
m_MyLocationOverlay.disableCompass();
}
現在可以 Build 來測試看看。
如果用模擬器來跑的話,記得從模擬器上送出位置。
接下來,我們要來加上我們自己的標記。
首先,我抓了一個免費的藍色圖釘圖示。加到 Android 專案的 resource 裡,名稱叫做 pin_blue。
然後,我們從 Map API 中的 ItemizedOverlay 抽象介面,實做一個叫做 PriLocOverlays 的類別。
public class PriLocOverlays extends ItemizedOverlay<OverlayItem>
{
private static int MAXNUM = 50;
private OverlayItem m_Overlays[] = new OverlayItem[MAXNUM];
private int m_nCount = 0;
public PriLocOverlays(Drawable defaultMarker) {
super(boundCenterBottom(defaultMarker));
// TODO Auto-generated constructor stub
}
@Override
protected OverlayItem createItem(int i) {
// TODO Auto-generated method stub
return m_Overlays[i];
}
@Override
public int size() {
// TODO Auto-generated method stub
return m_nCount;
}
public void addOverlay(OverlayItem overlay)
{
if (m_nCount < MAXNUM)
{
m_Overlays[m_nCount] = overlay;
m_nCount++;
setLastFocusedIndex(-1);
populate();
}
}
}
OverlayItem 的陣列,我們必須要自己管理。我很簡單的只是用個固定陣列來放。然後再加個記數的變數。
createItem 以及 size 兩個函式是我們要實做的,就簡單的傳回陣列裡的物件跟數量就好了。要注意的是,這個 createItem 函式,並不真的需要去產生一個 Item,每次 Map View 需要更新 Overlay 時,都會呼叫這個函式。
在我們自己的 addOverlayItem 內,我們需要呼叫 populate 函式,通知 Map View 來更新這個 Overlay。並且,最好是在呼叫 populate 之前,呼叫 setLastFocusedIndex(-1),清掉之前的 Focus Item,否則咧,會因為找不到之前的 Focus Item 而讓 App Crash 的。( 我實際接到過這個問題的 Bug 回報,還好已經有神人找到問題解答了... )
接著,改 Main Activity,加入 PriLocOverlays 的變數,並且在 onCreate 中建立它。
Drawable drawable = this.getResources().getDrawable(R.drawable.pin_blue);
m_PrivateLocOverlay = new PriLocOverlays(drawable);
m_MapView.getOverlays().add(m_PrivateLocOverlay);
我們還需要有一個把目前位置建立成 OverlayItem 加入到 PrivateLocOverlay 裡的功能。就做在 Option Menu 裡吧...
在 Main Activity 加入函式。
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.menu_settings)
{
OverlayItem overlay = new OverlayItem(m_MyLocationOverlay.getMyLocation(), "Test Loc", "");
m_PrivateLocOverlay.addOverlay(overlay);
//requestAddCurrentLocation();
return true;
}
return super.onOptionsItemSelected(item);
}
於是乎,程式跑起來就像這樣。
呃...
本來想,就先寫到這樣吧,後來又覺得該寫下這個...
我們在 PriLocOverlays 類別裡,可以覆寫 onTap ( int index ) 這個函式。
當地圖上的標記被點選到的時候,onTap 函式會被呼叫。這時候,我們可以用 index 取出 OverlayItem,進行處理。
@Override
protected boolean onTap(int index)
{
OverlayItem overlayItem = m_Overlays[index];
Toast.makeText(m_Activity, overlayItem.getTitle(), Toast.LENGTH_LONG).show();
// TODO Auto-generated method stub
return super.onTap(index);
}
我沒多做什麼,就是用 Toast 顯示了一下。
結果就類似這樣。