向 Android 应用添加地图
添加地图的基本步骤如下:
- (此步骤只需执行一次。) 按照项目配置指南中的步骤获取 API,获得密钥,然后 将所需属性添加到您的 Android 清单文件中。
- 向将处理地图的
Activity
添加Fragment
对象。 最简单的实现方式是,向Activity
的布局文件添加<fragment>
元素。 - 实现
OnMapReadyCallback
接口,并 使用onMapReady(GoogleMap)
回调方法获取GoogleMap
对象的句柄。GoogleMap
对象是 对地图本身的内部表示。 如需设置地图的视图选项 ,您需要修改其GoogleMap
对象。 - 调用 Fragment 上的
getMapAsync()
以注册 回调。
以下是有关各步骤的更多详情。
添加 Fragment
向 Activity 的布局文件添加 <fragment>
元素,以定义 Fragment
对象。 在该元素中,将 android:name
属性设置为 "com.google.android.gms.maps.MapFragment"
。 此操作会自动将MapFragment
附加到 Activity。
以下布局文件包含一个 <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"/>
您还可以向代码中的 Activity
添加 MapFragment
。 如需实现此目的,请创建一个新的 MapFragment
实例,然后调用 FragmentTransaction.add()
,将 Fragment
添加到当前Activity
mMapFragment = MapFragment.newInstance();
FragmentTransaction fragmentTransaction =
getFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.my_container, mMapFragment);
fragmentTransaction.commit();
添加地图代码
如需在您的应用内使用地图,您需要实现 OnMapReadyCallback
接口,并在 MapFragment
对象或 MapView
对象上设置回调实例。 本教程使用的是 MapFragment
,因为这是向应用添加地图的最常用方法。 第一步是实现回调接口:
public class MainActivity extends FragmentActivity
implements OnMapReadyCallback {
...
}
在您的 Activity
的 onCreate()
方法中,将布局文件设置为内容视图。 例如,如果布局文件的名称是 main.xml
,请使用以下代码:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
...
}
通过调用 FragmentManager.findFragmentById()
, 将您的 <fragment>
元素的资源 ID 传递给它,来获取 Fragment 的句柄。 请注意, 当您生成布局文件时,Android 项目中会自动添加资源 ID R.id.map
。
然后使用 getMapAsync()
设置 Fragment 上的回调。
MapFragment mapFragment = (MapFragment) getFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
注:Google Maps Android API 需要 API 级别 12 或更高级别,才能支持 MapFragment
对象。如果您的目标是低于 API级别 12 的应用,可通过 SupportMapFragment
类访问同一功能。 您还必须提供 Android 支持库。
注:必须从主线程调用 getMapAsync()
,回调将在主线程中执行。 如果用户设备上未安装 Google Play 服务,则用户安装 Play 服务后才会触发回调。
使用 onMapReady(GoogleMap)
回调方法获取 GoogleMap
对象的句柄。 回调将在地图做好使用准备时触发。 它会提供 GoogleMap
的非空实例。 举例来说,您可以利用 GoogleMap
对象为地图设置视图选项,或者添加标记。
@Override
public void onMapReady(GoogleMap map) {
map.addMarker(new MarkerOptions()
.position(new LatLng(0, 0))
.title("Marker"));
}
在activity中添加地图:
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map); mapFragment.getMapAsync(this);
<fragment xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/map" class="com.google.android.gms.maps.SupportMapFragment" android:layout_width="match_parent" android:layout_height="match_parent" />
当然要重写OnMapReadyCallback
在fragment中添加地图
View view = inflater.inflate(R.layout.fragment_home_main_fragment__googl_map, null); mapView = (MapView) view.findViewById(R.id.google_map); mapView.onCreate(savedInstanceState); mapView.getMapAsync(this);
这里使用MapView实现在XML中布局
<com.google.android.gms.maps.MapView android:id="@+id/google_map" android:layout_width="match_parent" android:layout_height="match_parent"></com.google.android.gms.maps.MapView>
地图对象
Google Maps Android API 允许您在 Android 应用中显示 Google 地图。 这些地图与您在 Google Maps for Mobile (GMM) 应用中所见的地图具有相同的外观,并且该 API 公开的许多功能也是相同的。 GMM 应用与 Google Maps Android API 显示的地图之间存在两个明显差异:
- 该 API 显示的地图图块不包含任何个性化内容,如个性化智能图标。
- 并非地图上的所有图标均可点击。 例如,中转站图标便无法点击。 不过,您向地图添加的标记可以点击, 并且该 API 具有一个侦听器回调接口,用于进行各种标记交互。
除了地图功能外,该 API 还支持符合 Android UI 模型的全系列交互。 例如,您可以通过定义可响应用户手势的侦听器来设置与地图的交互。
使用地图对象时的关键类是 GoogleMap
类。 GoogleMap
在您的应用内为地图对象建模。 在您的 UI 内,地图将由 MapFragment
对象或 MapView
对象表示。
GoogleMap
自动处理下列操作:
- 连接到 Google 地图服务
- 下载地图图块。
- 在设备屏幕上显示图块。
- 显示如平移和缩放等各类控件。
- 通过移动和缩放地图响应平移和缩放手势
除了这些自动操作外,您还可以通过该 API 的对象和方法控制地图的行为。 例如,GoogleMap
具有可响应地图上点击动作和触摸手势的回调方法。 您还可以利用向GoogleMap
提供的对象在地图上设置标记图标以及为其添加叠层。
MapFragment
MapFragment
是 Android Fragment
类的一个子类,用于在 Android Fragment 中放置地图。MapFragment
对象充当地图容器,并提供对 GoogleMap
对象的访问权。
与 View
不同,Fragment
表示的是 Activity 中的一种行为或用户界面的某一部分。 您可以将多个 Fragment 组合在一个 Activity 中来构建多窗格 UI,以及在多个 Activity 中重复使用某个 Fragment。请参阅有关 Fragment 的 Android 文档,以了解更多信息。
MapView
MapView
是 AndroidView
类的一个子类, 用于在 Android View
中放置地图。 View
表示屏幕的某个矩形区域, 是 Android 应用和小工具的基本构建基块。 MapView
与 MapFragment
很相似,它也充当地图容器,通过 GoogleMap
对象公开核心地图功能。
在完全交互模式下使用该 API 时,此类的用户必须将所有 Activity 生命周期方法都转发给 MapView
类中的相应方法。 举例来说,生命周期方法包括 onCreate()
、onDestroy()
、onResume()
和 onPause()
。 在精简模式下使用该 API 时,转发生命周期事件为可选操作。 如需了解详情,请参阅精简模式文档。
地图类型
Google Maps Android API 内提供了许多类型的地图。 地图类型支配着地图的整体表现。 例如, 地图集通常包含的政治地图侧重于显示边界,而道路地图则会显示某个城市或地区的所有道路。
Google Maps Android API 提供了四种地图,以及不显示任何地图的选项:
-
Normal
- 典型道路地图。 显示道路、一些人造景观以及 河流等重要的自然景观。 此外,还会显示道路和 景观标签。 Hybrid
- 添加了道路地图的卫星照片数据。 此外,还会显示道路 和景观标签。 Satellite
- 卫星照片数据。 不显示道路和景观标签。 Terrain
- 地形数据。 地图包含颜色、轮廓线和标签以及 透视阴影。 此外,还会显示一些道路和标签。 None
- 无图块。 地图将渲染为空网格,不加载任何图块。
更改地图类型
如需设置地图类型,请调用 GoogleMap
对象的 setMapType()
方法,传递 GoogleMap
中定义的其中一个类型常量。 例如,如需显示卫星地图:
GoogleMap map;
...
// Sets the map type to be "hybrid"
map.setMapType(GoogleMap.MAP_TYPE_HYBRID);
以下图像显示的是同一位置 normal 地图、hybrid 地图和 terrain 地图的比较:
室内地图
在高放大倍率下, 地图将显示机场、购物中心、大型零售店和中转站等室内场所的平面图。 这些平面图称作室内地图, 将为“normal”和“satellite”地图类型(GoogleMap.MAP_TYPE_NORMAL
和GoogleMap.MAP_TYPE_SATELLITE
)显示。 它们会在用户放大地图时自动启用,在用户缩小地图时自动消失。
在 API 中使用室内地图
下面概要列出了 API 中的室内地图功能:
- 您可以通过调用
GoogleMap.setIndoorEnabled(false)
禁用室内地图。 默认情况下,室内地图处于启用状态。 室内地图一次只能显示在一幅地图上。 默认情况下,这是向您的应用添加的第一幅地图。 如果您想在其他地图上显示室内地图, 请在第一幅地图上禁用它们, 然后在第二幅地图上调用setIndoorEnabled(true)
。 - 如需禁用默认层级选取器(楼层选取器),请调用
GoogleMap.getUiSettings().setIndoorLevelPickerEnabled(false)
。 如需了解更多详情,请参阅与地图交互。 - GoogleMap 上的一个接口
OnIndoorStateChangeListener
允许您设置在一栋新建筑获得焦点或者激活建筑内的新楼层时调用的侦听器。如需了解更多详情,请参阅与地图交互。 GoogleMap.getFocusedBuilding()
为您获取当前获得焦点的建筑。 您随后可以通过调用IndoorBuilding.getActiveLevelIndex()
找到当前激活的楼层。 请参阅参考文档, 以了解IndoorBuilding
对象和IndoorLevel
对象中提供的所有信息。
添加平面图
选择位置 中提供了室内地图(平面图)。 如果您想在应用中突出显示的建筑没有平面图数据,您可以:
- 直接向 Google 地图添加平面图。 这样做可以将您的平面图提供给 Google 地图的所有用户。
- 将平面图以底面叠层 或 图块叠层 形式显示在您的地图上。 这样一来,只有您的应用的用户才能查看平面图。
配置初始状态
Maps API 允许您根据您的应用的需求配置地图的初始状态。 您可以指定以下内容:
- 画布位置,包括:位置、缩放比例、方位和倾斜角度。
- 地图类型
- 缩放按钮和/或指南针是否出现在屏幕上
- 用户在操纵摄像头时可使用的手势
- 是否启用了精简模式。 精简模式地图是指地图的一种位图图像, 它支持完整 API 提供的一部分功能。
如果您已将地图添加到 Activity 的布局文件,可以通过 XML 配置地图的初始状态;如果您是以编程方式添加地图,则可以编程方式进行配置。
使用 XML 属性
此部分介绍在您利用 XML 布局文件向应用添加地图的情况下如何设置地图的初始状态。
Maps API 为 MapFragment
或 MapView
定义了一组自定义 XML 属性,您可以利用它们直接在布局文件内配置地图的初始状态。 当前定义的属性如下:
mapType
。 它用于指定要显示的地图类型。 有效 值包括none
、normal
、hybrid
、satellite
和terrain
。cameraTargetLat
、cameraTargetLng
、cameraZoom
、cameraBearing
、cameraTilt
。 它们用于指定画布的初始位置。uiZoomControls
、uiCompass
。 它们用于指定您是否希望将缩放控件和指南针出现在地图上。uiZoomGestures
、uiScrollGestures
、uiRotateGestures
、uiTiltGestures
。 它们用于指定在与地图交互时启用/禁用的手势。zOrderOnTop
。 控制地图视图的表面是否覆盖在其窗口上。 请参阅 SurfaceView.setZOrderOnTop(boolean),了解更多详情。 请注意,如果指定此属性,将会覆盖所有其他可能出现在地图上的视图(例如缩放控件、my location 按钮)。useViewLifecycle
。 只对MapFragment
有效。 此属性指定是否应将地图的生命周期与 Fragment 的视图或 Fragment 本身关联。liteMode
。 值true
会将地图设置为精简模式。 精简模式地图是指地图的一种位图图像,它支持完整 API 提供的一部分功能。 该属性的默认值 为false
。
如需在您的 XML 布局文件内使用这些自定义属性,您必须先添加下列命名空间声明。 您可以选择任何命名空间,不必一定要选择 map
:
xmlns:map="http://schemas.android.com/apk/res-auto"
然后您就可以像使用标准 Android 属性那样,向您的布局组件中添加带 map:
前缀的属性。
下面这段 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"/>
注:如果您使用的是 Google Maps Mobile SDK for Work,则必须为每个属性添加 m4b_
前缀。 例如,在指定地图类型属性时,请使用 m4b_mapType
而非 mapType
。 或者,在指定缩放控件时使用m4b_uiZoomControls
而非 uiZoomControls
,依此类推。
以编程方式
此部分介绍在您以编程方式向应用添加地图的情况下如何设置地图的初始状态。
如果您以编程方式添加了 MapFragment
(或 MapView
),则可通过传入进行了选项指定的GoogleMapOptions
对象配置其初始状态。 可供您使用的选项与通过 XML 设置时可用的选项完全相同。 您可以创建下面这样的 GoogleMapOptions
对象:
GoogleMapOptions options = new GoogleMapOptions();
然后对其进行如下配置:
options.mapType(GoogleMap.MAP_TYPE_SATELLITE)
.compassEnabled(false)
.rotateGesturesEnabled(false)
.tiltGesturesEnabled(false);
如需在创建地图时应用这些选项,请执行下列操作之一:
- 如果您使用的是
MapFragment
,请使用MapFragment.newInstance(GoogleMapOptions options)
静态出厂方法构建 Fragment 并传入您的自定义配置选项 - 如果您使用的是
MapView
,请使用MapView(Context, GoogleMapOptions)
构造函数并传入您的自定义配置选项