添加自定样式的地图

请选择平台: Android iOS JavaScript

本教程以“夜间模式”为自定义样式范例,介绍了如何在 Android 应用中添加包含自定义样式的地图。

您可以使用样式选项来自定义标准 Google 地图样式的外观风格,更改道路、公园、商家和其他地图注点等地图项的视觉显示效果。也就是说,您可以突出地图的特定组件,或让地图与应用的样式协调一致。

样式设置仅适用于 normal 地图类型,不会影响室内地图

获取代码

从 GitHub 克隆或下载 Google Maps Android API v2 示例代码库

设置您的开发项目

请按照以下步骤在 Android Studio 中创建教程项目。

  1. 下载安装 Android Studio。
  2. Google Play 服务软件包添加到 Android Studio。
  3. 克隆或下载 Google Maps Android API v2 示例代码库(如果您在开始阅读本教程之前尚未执行此操作)。
  4. 导入教程项目:

    • 在 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 密钥

  1. 修改项目的 gradle.properties 文件。
  2. 将您的 API 密钥粘贴到 GOOGLE_MAPS_API_KEY 属性的值中。在您构建应用时,Gradle 会将 API 密钥复制到应用的 Android 清单中。

    GOOGLE_MAPS_API_KEY=PASTE-YOUR-API-KEY-HERE
    

构建并运行应用

  1. 将 Android 设备连接到您的计算机。按照说明在您的 Android 设备上启用开发者选项,并配置您的系统,使之检测该设备。您也可以使用 Android 虚拟设备 (AVD) 管理器来配置虚拟设备。选择模拟器时,请务必选择一个包含 Google API 的映像。如需了解详情,请参阅入门指南
  2. 在 Android Studio 中,点击 Run 菜单选项(或 Play 按钮图标)。按提示选择设备。

Android Studio 会调用 Gradle 来构建应用,然后在设备或模拟器上运行该应用。您将看到一个具有深色(夜间模式)样式的地图,与本页上的图像类似。

问题排查:

了解代码

本部分教程介绍了 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 样式声明的详细信息

自定样式的地图利用以下两种概念,将颜色和其他样式更改应用到地图:

  • 选择器:指定可以在地图上设置样式的地理区域组件,包括道路、公园、水体等项目以及它们的标签。选择器包括地图项和元素,分别以 featureTypeelementType 属性来表示。
  • 样式器:可应用于地图元素的颜色和可见性属性,通过色调、颜色和亮度/灰度系数值的组合来定义显示的颜色。

有关 JSON 样式设置选项的详细说明,请参阅样式参考

Maps Platform 样式设置向导

使用 Maps Platform 样式设置向导可以快速生成 JSON 样式设置对象。Maps SDK for Android 支持与 Maps JavaScript API 相同的样式声明。

后续步骤

了解如何通过样式设置来隐藏地图上的地图项