本教程以“夜间模式”为自定义样式范例,介绍了如何在 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 相同的样式声明。
后续步骤
了解如何通过样式设置来隐藏地图上的地图项。





