地圖物件

地圖是由 GoogleMapMapFragment 類別在 API 中呈現。

程式碼範例

GitHub 上的 ApiDemos 存放區包含說明如何使用 GoogleMap 物件和 SupportMapFragment 的範例:

在 Android 應用程式中加入地圖

加入地圖的基本步驟如下:

  1. (這個步驟只須執行一次。)按照專案設定指南中的步驟取得 API,並存取金鑰,然後在 Android 資訊清單中新增必要的屬性。
  2. Fragment 物件新增至處理地圖的 Activity 物件。最簡單的做法是在 Activity 的版面配置檔案中加入 <fragment> 元素。
  3. 導入 OnMapReadyCallback 介面並使用 onMapReady(GoogleMap) 回呼方法取得 GoogleMap 物件的處理常式。GoogleMap 物件是地圖本身的內部表示法。如要設定地圖的檢視選項,請修改其 GoogleMap 物件。
  4. 呼叫片段的 getMapAsync() 以註冊回呼。

以下是每個步驟的詳細說明。

新增片段

在活動的版面配置檔案中加入 <fragment> 元素,以定義 Fragment 物件。在這個元素中,將 android:name 屬性設為 "com.google.android.gms.maps.MapFragment"。系統會自動將 MapFragment 附加至活動。

以下版面配置檔案包含 <fragment> 元素:

<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    android:name="com.google.android.gms.maps.MapFragment"
    android:id="@+id/map"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

您也可以在程式碼中將 MapFragment 新增到 Activity。做法是建立新的 MapFragment 例項,然後呼叫 FragmentTransaction.add() 即可將 Fragment 新增到目前的 Activity

 mMapFragment = MapFragment.newInstance();
 FragmentTransaction fragmentTransaction =
         getFragmentManager().beginTransaction();
 fragmentTransaction.add(R.id.my_container, mMapFragment);
 fragmentTransaction.commit();

新增地圖程式碼

如要在應用程式中使用地圖,您必須導入 OnMapReadyCallback 介面,並設定 MapFragmentMapView 物件的回呼例項。本教學課程使用的是 MapFragment,因為這是在應用程式中加入地圖最常見的方法。第一步是導入回呼介面:

public class MainActivity extends FragmentActivity
    implements OnMapReadyCallback {
...
}

ActivityonCreate() 方法中,將版面配置檔案設為內容檢視。舉例來說,如果版面配置檔案的名稱是 main.xml,請使用以下程式碼:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    ...
}

呼叫 FragmentManager.findFragmentById() 並將 <fragment> 元素的資源 ID 傳遞給該程式碼,以取得片段的處理常式。請注意,建立版面配置檔案時,系統會自動將資源 ID R.id.map 新增至 Android 專案。

然後使用 getMapAsync() 設定片段的回呼。

MapFragment mapFragment = (MapFragment) getFragmentManager()
    .findFragmentById(R.id.map);
mapFragment.getMapAsync(this);

使用 onMapReady(GoogleMap) 回呼方法取得 GoogleMap 物件的處理常式。地圖準備就緒時就會觸發回呼,並提供非空值的 GoogleMap 例項。舉例來說,您可以使用 GoogleMap 物件來設定地圖的檢視選項,或是新增標記。

@Override
public void onMapReady(GoogleMap map) {
    map.addMarker(new MarkerOptions()
        .position(new LatLng(0, 0))
        .title("Marker"));
}

地圖物件

Maps SDK for Android 可讓您在 Android 應用程式中顯示 Google 地圖。這些地圖和您在 Google 地圖行動版應用程式中看到的地圖外觀相同,且 API 也提供許多同樣的地圖項目。Google 地圖行動版應用程式與 Maps SDK for Android 顯示的地圖有下列兩項較明顯的差異:

  • API 顯示的地圖圖塊不包含任何個人化內容 (例如個人化智慧圖示)。
  • 地圖上有部分圖示無法點擊,例如大眾運輸站點圖示。不過,您新增至地圖的標記皆為可點擊,且 API 提供事件監聽器回呼介面,供您查看各種標記互動。

除了地圖功能外,API 還支援 Android 使用者介面模型中可用的所有互動。例如,您可以定義回應使用者手勢的事件監聽器,藉此設定與地圖的互動。

使用地圖物件時的金鑰類別為 GoogleMap 類別。GoogleMap 會為應用程式中的地圖物件建立模型。在使用者介面中,地圖會以 MapFragmentMapView 物件表示。

GoogleMap 會自動處理下列作業:

  • 連線到 Google 地圖服務。
  • 下載地圖圖塊。
  • 顯示在設備屏幕上的瓷磚。
  • 顯示各種控件,如平移和縮放。
  • 藉由移動地圖及放大/縮小,回應平移和縮放手勢。

除了這些自動操作之外,您也可以使用 API 的物件和方法控制地圖的行為。舉例來說,GoogleMap 的回呼方法會回應地圖上的按鍵動作和輕觸手勢。您也可以使用您提供給 GoogleMap 的物件,在地圖上設定標記圖示和新增疊加層。

MapFragment

MapFragment 是 Android Fragment 類別的子類別,可讓您將地圖放置在 Android 片段中。MapFragment 物件是當做地圖的容器使用,且提供 GoogleMap 物件的存取權。

View 不同的是,Fragment 代表活動中的特定行為或特定使用者介面部分。您可以將多個片段結合為單一活動,建立多窗格使用者介面,並在多個活動中重複使用單一片段。詳情請參閱片段中的 Android 說明文件。

MapView

MapView 是 Android View 類別的子類別,可讓您將地圖放置在 Android View 中。View 代表螢幕的矩形區域,其為 Android 應用程式和小工具的基礎建置區塊。MapViewMapFragment 很像,可當做地圖的容器使用,且會透過 GoogleMap 物件展示核心地圖功能。

完全互動模式中使用 API 時,MapView 類別的使用者必須將下列活動生命週期方法轉送至 MapView 類別中的對應方法:onCreate()onStart()onResume()onPause()onStop()onDestroy()onSaveInstanceState()onLowMemory()。GitHub 上的 ApiDemos 存放區包含說明如何轉送活動生命週期方法的範例。在精簡模式中使用 API 時,您可以自行選擇是否要轉送生命週期事件。詳情請參閱精簡模式說明文件。

地圖類型

Maps SDK for Android 中提供多種類型的地圖。地圖的類型決定了地圖整體的表示方式。舉例來說,地圖集通常含有以顯示行政區界線為主的行政區地圖,以及顯示特定城市或地區所有道路的道路地圖。

Maps SDK for Android 提供以下四種類型的地圖,或者您也可以選擇完全不顯示地圖:

一般
一般道路地圖。顯示道路、部分人造設施,以及河流等重要自然景觀,也顯示道路和地圖項目標籤。
混合
加入道路地圖的衛星相片資料,也顯示道路和地圖項目標籤。
衛星
衛星相片資料。不顯示道路和地圖項目標籤。
地形
地形資料。這種地圖包含顏色、等高線和標籤以及透視陰影,也顯示部分道路和地圖項目標籤。
無圖塊。地圖會顯示為未載入任何圖塊的空格線。

變更地圖類型

如要設定地圖類型,請呼叫 GoogleMap 物件的 setMapType() 方法,傳遞 GoogleMap 中定義的其中一個類型常數。舉例來說,如要顯示衛星地圖:

GoogleMap map;
...
// Sets the map type to be "hybrid"
map.setMapType(GoogleMap.MAP_TYPE_HYBRID);

下方的圖片顯示同個位置的一般、混合和地形地圖比較:

地圖類型比較

室內地圖

在高倍縮放時,地圖會顯示室內空間 (例如機場、購物中心、大型零售商店和大眾運輸車站) 的樓層平面圖。這些樓層平面圖稱為「室內地圖」,會在「一般」和「衛星」地圖類型 (GoogleMap.MAP_TYPE_NORMALGoogleMap.MAP_TYPE_SATELLITE) 中顯示。系統會在使用者放大地圖時自動啟用這項功能,並在縮小地圖時逐漸消失。

淘汰通知:在日後推出的版本中,只有 normal 地圖提供室內地圖。也就是說,日後自該版本推出後,satelliteterrainhybrid 地圖將不再支援室內地圖。即使屆時不再支援室內地圖,isIndoorEnabled() 也會繼續照常傳回透過 setIndoorEnabled() 設定的值。根據預設,setIndoorEnabledtrue。當這些地圖類型不再支援室內地圖,版本資訊便會公告相關資訊。

室內地圖範例

在 API 中使用室內地圖

以下是 API 中的室內地圖功能摘要:

基本地圖的樣式設定不會影響室內地圖。

新增樓層平面圖

特定位置提供室內地圖 (樓層平面圖)。如果無法取得您想要在應用程式中突顯的建築物平面圖資料,您可以:

  • 直接在 Google 地圖中新增樓層平面圖。如此一來,Google 地圖的所有使用者都能使用您的樓層平面圖。
  • 在地圖上以區域疊加層圖塊疊加層的方式顯示樓層平面圖。如採用這種方式,則只有您應用程式的使用者才能查看您的樓層平面圖。

路況圖層

您可以讓使用者查看疊加在地圖上的車流量資訊,清楚呈現當地的路況。您可以透過呼叫 setTrafficEnabled() 方法來開啟或關閉路況圖層,呼叫 isTrafficEnabled() 方法則可判斷路況圖層目前是否已啟用。以下範例顯示路況圖層在地圖上的可能顯示方式。

顯示路況圖層的 Google 地圖

設定初始狀態

Maps API 可讓您根據應用程式的需求設定地圖的初始狀態。您可以指定下列項目:

  • 攝影機位置,包括:位置、縮放、航向和傾斜。 如要進一步瞭解攝影機位置,請參閱攝影機和檢視畫面
  • 地圖類型。
  • 螢幕上是否要顯示縮放按鈕和/或指南針。
  • 使用者可用來操控攝影機的手勢。
  • 是否啟用精簡模式。精簡模式地圖是地圖的點陣圖圖片,可支援由完整 API 提供的部分功能。

有兩種方式可讓您設定地圖的初始狀態。如果您已將地圖加入活動的版面配置檔案,請透過 XML 設定;如果您是透過程式輔助加入地圖,則請同樣以程式輔助方式設定。

使用 XML 屬性

本節說明如果您已使用 XML 版面配置檔案將地圖加入應用程式,該如何設定地圖的初始狀態。

Maps API 為 MapFragmentMapView 定義了一組自訂 XML 屬性,可讓您直接從版面配置檔案設定地圖的初始狀態。以下屬性目前已定義:

  • mapType。這個屬性可讓您指定要顯示的地圖類型。有效值包括:nonenormalhybridsatelliteterrain
  • cameraTargetLatcameraTargetLngcameraZoomcameraBearingcameraTilt。這些可讓您指定攝影機的初始位置。 請參閱這裡,瞭解攝影機位置及其屬性的詳細資料。
  • uiZoomControlsuiCompass。這些可讓您指定是否要在地圖上顯示縮放控制項和指南針。詳情請參閱 UiSettings
  • uiZoomGesturesuiScrollGesturesuiRotateGesturesuiTiltGestures。這些可讓您指定要啟用/停用的地圖互動手勢。詳情請參閱 UiSettings
  • zOrderOnTop。控制地圖檢視的介面是否已置於其視窗上方。詳情請參閱 SurfaceView.setZOrderOnTop(boolean)。請注意,這項設定會涵蓋地圖上顯示的所有其他檢視 (例如縮放控制項和「我的位置」按鈕)。
  • useViewLifecycle。必須使用 MapFragment 才會生效。這個屬性用來指定地圖的生命週期是否應繫結至片段本身或其檢視畫面。詳情請參閱這裡
  • liteModetrue 的值,可將地圖設為精簡模式。精簡模式地圖是地圖的點陣圖圖片,可支援由完整 API 提供的一部分功能。此屬性的預設值為 false

如要在您的 XML 版面配置檔案中使用這些自訂屬性,您必須先加入下列命名空間宣告。您可以選擇任何命名空間,不一定要是 map

xmlns:map="http://schemas.android.com/apk/res-auto"

接著,您就可以在版面配置元件中加入包含 map: 前置字元的屬性,就像使用標準 Android 屬性時一樣。

下列 XML 程式碼片段顯示如何搭配部分自訂選項設定 MapFragment。相同的屬性也可以套用至 MapView

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:map="http://schemas.android.com/apk/res-auto"
  android:name="com.google.android.gms.maps.SupportMapFragment"
  android:id="@+id/map"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  map:cameraBearing="112.5"
  map:cameraTargetLat="-33.796923"
  map:cameraTargetLng="150.922433"
  map:cameraTilt="30"
  map:cameraZoom="13"
  map:mapType="normal"
  map:uiCompass="false"
  map:uiRotateGestures="true"
  map:uiScrollGestures="false"
  map:uiTiltGestures="true"
  map:uiZoomControls="false"
  map:uiZoomGestures="true"/>

程式輔助方式

本節說明如果您已透過程式輔助方式將地圖加入應用程式,該如何設定地圖的初始狀態。

如果您已透過程式輔助方式新增 MapFragment (或 MapView),則可以透過傳入指定選項的 GoogleMapOptions 物件來設定其初始狀態。您可以使用的選項與 XML 提供的選項完全相同。您可建立如下所示的 GoogleMapOptions 物件:

GoogleMapOptions options = new GoogleMapOptions();

然後依照下列方式設定:

options.mapType(GoogleMap.MAP_TYPE_SATELLITE)
    .compassEnabled(false)
    .rotateGesturesEnabled(false)
    .tiltGesturesEnabled(false);

如要在建立地圖時套用這些選項,請執行下列其中一項操作:

地圖邊框間距

這部影片會顯示地圖邊框間距的範例。

Google 地圖的設計會填滿由容器元素定義的整個區域,通常是 MapViewMapFragment。地圖的顯示方式和行為模式取決於地圖容器的維度:

  • 攝影機的目標會反映設有邊框間距的區域中心。
  • 地圖控制項是依地圖邊緣決定其相對位置。
  • 版權聲明之類的法律資訊或是 Google 標誌,則沿著地圖的底部邊緣顯示。

您可以使用 GoogleMap 增加地圖邊緣周圍的邊框間距。setPadding() 方法。地圖將繼續填滿整個容器,但文字和控制項位置、地圖手勢及攝影機動作將有如被放置於一個較小的空間,順應改變行為。這將導致以下變化:

  • 透過 API 呼叫或按下按鈕 (例如「指南針」、「我的位置」和「縮放按鈕」) 產生的攝影機動作將會以相對於設有邊框間距區域的方式進行。
  • getCameraPosition() 會返回設有邊框間距區域的中心。
  • ProjectiongetVisibleRegion() 會返回設有邊框間距的區域。
  • UI 控制項將從容器的邊緣偏移,偏移距離為指定的像素數。

設計與地圖中特定部分重疊的使用者介面時,邊框間距是頗為實用的功能。舉例來說,在下方圖片中,地圖的頂部邊緣和右邊緣都設有邊框間距。可見地圖控制項和法律文字將沿著設有邊框間距區域的邊緣顯示,以綠色表示;地圖將繼續填滿整個容器,以藍色表示。在這個範例中,您可以讓選單浮動在地圖右側,且不對地圖控制項做模糊處理。

地圖邊框間距

將您的地圖本地化

當您在應用程式中加入 MapViewMapFragment 時,系統會根據使用者的裝置設定和位置,在地圖上以適當語言顯示文字元素。在 Gradle 檔案中加入 resConfigs 項目,即可將應用程式限制為使用所有支援語言中的特定一部分語言。如要移除不使用的語言,這個方法非常實用,同時也可減少應用程式的二進位檔大小。例如:

defaultConfig {
    resConfigs "en", "fr", "es", "zh", "de", "ja", "ru", "ko", "pt", "in"
}

進一步瞭解如何將 Android 應用程式本地化