本教程以“夜间模式”为自定义样式范例,介绍了如何在 Android 应用中添加包含自定义样式的地图。
您可以使用样式选项来自定义标准 Google 地图样式的外观风格,更改道路、公园、商家和其他地图注点等地图项的视觉显示效果。也就是说,您可以突出地图的特定组件,或让地图与应用的样式协调一致。
样式设置仅适用于 normal
地图类型,不会影响室内地图。
获取代码
从 GitHub 克隆或下载 Google Maps Android API v2 示例代码库。
设置您的开发项目
请按照以下步骤在 Android Studio 中创建教程项目。
- 下载并安装 Android Studio。
- 将 Google Play 服务软件包添加到 Android Studio。
- 克隆或下载 Google Maps Android API v2 示例代码库(如果您在开始阅读本教程之前尚未执行此操作)。
导入教程项目:
- 在 Android Studio 中,依次选择 File > New > Import Project。
- 前往 Google Maps Android API v2 示例代码库的下载位置。
- 在以下位置找到 StyledMap 项目:
PATH-TO-SAVED-REPO/android-samples/tutorials/StyledMap
- 选择项目目录,然后点击 OK。Android Studio 现在将使用 Gradle 构建工具来构建您的项目。
获取 API 密钥并启用必要的 API
如需完成本教程,您需要一个已获得 Maps SDK for Android 使用授权的 Google API 密钥。
点击下面的按钮以获取密钥并激活 API。
如需了解详情,请参阅有关获取 API 密钥的指南。
向您的应用添加 API 密钥
- 修改项目的
gradle.properties
文件。 将您的 API 密钥粘贴到
GOOGLE_MAPS_API_KEY
属性的值中。在您构建应用时,Gradle 会将 API 密钥复制到应用的 Android 清单中。GOOGLE_MAPS_API_KEY=PASTE-YOUR-API-KEY-HERE
构建并运行应用
- 将 Android 设备连接到您的计算机。按照说明在您的 Android 设备上启用开发者选项,并配置您的系统,使之检测该设备。您也可以使用 Android 虚拟设备 (AVD) 管理器来配置虚拟设备。选择模拟器时,请务必选择一个包含 Google API 的映像。如需了解详情,请参阅入门指南。
- 在 Android Studio 中,点击 Run 菜单选项(或 Play 按钮图标)。按提示选择设备。
Android Studio 会调用 Gradle 来构建应用,然后在设备或模拟器上运行该应用。您将看到一个具有深色(夜间模式)样式的地图,与本页上的图像类似。
问题排查:
- 如果您没有看到地图,请检查您是否已按照上文中的说明获取 API 密钥并将其添加到该应用。为此,可在 Android Studio 的 Android Monitor 中检查日志,看看是否有关于 API 密钥的错误消息。
- 使用 Android Studio 调试工具查看日志并调试应用。
了解代码
本部分教程介绍了 StyledMap 应用最重要的部分,以帮助您了解如何构建类似的应用。
添加包含 JSON 样式对象的资源
将资源添加到您的开发项目,其中包含 JSON 格式的样式声明。您可以使用原始资源或字符串,如下例所示。
原始资源
在 /res/raw/style_json.json
中定义一个原始资源,其中包含用于夜间模式样式的 JSON 样式声明:
字符串资源
在 /res/values/style_strings.xml
中定义一个字符串资源,其中包含用于夜间模式样式的 JSON 样式声明。本教程使用字符串名称 style_json
。在此文件中,您需要使用一个反斜杠来转义引号:
将一个 JSON 样式对象传递到地图
若要设置地图样式,请调用 GoogleMap.setMapStyle()
,传递一个包含 JSON 格式的样式声明的 MapStyleOptions
对象。
原始资源
以下代码示例假定您的项目包含一个名为 style_json
的原始资源:
// Copyright 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.example.styledmap; import android.content.res.Resources; import android.os.Bundle; import android.util.Log; import androidx.appcompat.app.AppCompatActivity; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.OnMapReadyCallback; import com.google.android.gms.maps.SupportMapFragment; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.MapStyleOptions; /** * A styled map using JSON styles from a raw resource. */ public class MapsActivityRaw extends AppCompatActivity implements OnMapReadyCallback { private static final String TAG = MapsActivityRaw.class.getSimpleName(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Retrieve the content view that renders the map. setContentView(R.layout.activity_maps_raw); // Get the SupportMapFragment and register for the callback // when the map is ready for use. SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map); mapFragment.getMapAsync(this); } /** * Manipulates the map when it's available. * The API invokes this callback when the map is ready for use. */ @Override public void onMapReady(GoogleMap googleMap) { try { // Customise the styling of the base map using a JSON object defined // in a raw resource file. boolean success = googleMap.setMapStyle( MapStyleOptions.loadRawResourceStyle( this, R.raw.style_json)); if (!success) { Log.e(TAG, "Style parsing failed."); } } catch (Resources.NotFoundException e) { Log.e(TAG, "Can't find style. Error: ", e); } // Position the map's camera near Sydney, Australia. googleMap.moveCamera(CameraUpdateFactory.newLatLng(new LatLng(-34, 151))); } }
布局 (activity_maps_raw.xml
) 如下所示:
字符串资源
以下代码示例假定您的项目包含一个名为 style_json
的字符串资源:
package com.example.styledmap; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.Log; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.OnMapReadyCallback; import com.google.android.gms.maps.SupportMapFragment; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.MapStyleOptions; /** * A styled map using JSON styles from a string resource. */ public class MapsActivityString extends AppCompatActivity implements OnMapReadyCallback { private static final String TAG = MapsActivityString.class.getSimpleName(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Retrieve the content view that renders the map. setContentView(R.layout.activity_maps_string); // Get the SupportMapFragment and register for the callback // when the map is ready for use. SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map); mapFragment.getMapAsync(this); } /** * Manipulates the map when it's available. * The API invokes this callback when the map is ready for use. */ @Override public void onMapReady(GoogleMap googleMap) { // Customise the styling of the base map using a JSON object defined // in a string resource file. First create a MapStyleOptions object // from the JSON styles string, then pass this to the setMapStyle // method of the GoogleMap object. boolean success = googleMap.setMapStyle(new MapStyleOptions(getResources() .getString(R.string.style_json))); if (!success) { Log.e(TAG, "Style parsing failed."); } // Position the map's camera near Sydney, Australia. googleMap.moveCamera(CameraUpdateFactory.newLatLng(new LatLng(-34, 151))); } }
布局 (activity_maps_string.xml
) 如下所示:
有关 JSON 样式声明的详细信息
自定样式的地图利用以下两种概念,将颜色和其他样式更改应用到地图:
- 选择器:指定可以在地图上设置样式的地理区域组件,包括道路、公园、水体等项目以及它们的标签。选择器包括地图项和元素,分别以
featureType
和elementType
属性来表示。 - 样式器:可应用于地图元素的颜色和可见性属性,通过色调、颜色和亮度/灰度系数值的组合来定义显示的颜色。
有关 JSON 样式设置选项的详细说明,请参阅样式参考。
Maps Platform 样式设置向导
使用 Maps Platform 样式设置向导可以快速生成 JSON 样式设置对象。Maps SDK for Android 支持与 Maps JavaScript API 相同的样式声明。
后续步骤
了解如何通过样式设置来隐藏地图上的地图项。