Neste tutorial, mostramos como adicionar um mapa com estilização personalizada a um app Android. O tutorial usa o modo noturno como um exemplo de estilo personalizado.
Com as opções de estilo, você pode personalizar a apresentação dos mapas do Google, mudando o visual dos elementos, como vias, parques, empresas e outros pontos de interesse. Isso significa que é possível enfatizar componentes específicos ou deixar o mapa combinando com o estilo do seu app.
Os estilos só funcionam no tipo de mapa normal
. A estilização não afeta os mapas internos.
Acessar o código
Clone ou faça o download do repositório de exemplos da API Google Maps para Android v2 do GitHub (em inglês).
Configurar seu projeto de desenvolvimento
Siga estas etapas para criar o projeto de tutorial no Android Studio.
- Faça o download e instale o Android Studio.
- Adicione o pacote Google Play Services ao Android Studio.
- Clone ou faça o download do repositório de exemplos da API Google Maps Android v2 (link em inglês), caso não tenha feito isso no início do tutorial.
Importe o projeto do tutorial:
- No Android Studio, selecione File > New > Import Project.
- Acesse o local onde você salvou o repositório de exemplos da API Google Maps Android v2 após fazer o download.
- Encontre o projeto StyledMap neste local:
PATH-TO-SAVED-REPO/android-samples/tutorials/StyledMap
- Selecione o diretório do projeto e clique em OK. O Android Studio vai criar seu projeto usando a ferramenta Gradle.
Gerar uma chave de API e ativar as APIs necessárias
Para concluir este tutorial, você precisa de uma chave de API do Google que possa usar o SDK do Maps para Android.
Clique no botão abaixo para acessar uma chave e ativar a API.
Para conhecer mais detalhes, consulte o guia Acessar uma chave de API.
Adicionar a chave de API ao seu app
- Edite o arquivo
gradle.properties
do seu projeto. Cole a chave de API no valor da propriedade
GOOGLE_MAPS_API_KEY
. Quando você cria o app, o Gradle copia essa chave no manifesto do Android.GOOGLE_MAPS_API_KEY=PASTE-YOUR-API-KEY-HERE
Criar e executar o app
- Conecte um dispositivo Android ao computador. Siga as instruções se quiser ativar as opções para desenvolvedores no seu dispositivo Android e configurar o sistema de modo a detectar o aparelho. Também é possível usar o AVD Manager para configurar um dispositivo virtual. Ao escolher um emulador, selecione uma imagem que inclua as APIs do Google. Para mais detalhes, consulte o guia para iniciantes.
- No Android Studio, clique na opção de menu Run ou no ícone do botão de reprodução. Escolha um dispositivo quando solicitado.
O Android Studio invoca o Gradle para criar o app e, em seguida, executa o app no aparelho ou no emulador. Você terá acesso a um mapa com estilo escuro (modo noturno), semelhante à imagem desta página.
Solução de problemas:
- Se o mapa não aparecer, confirme se você recebeu uma chave de API e a incluiu no app, como descrito acima. Verifique se há mensagens de erro sobre essa chave no registro do Android Monitor do Android Studio.
- Use as ferramentas de depuração do Android Studio para conferir os registros e depurar o app.
Entender o código
Nesta seção do tutorial, explicamos as partes mais importantes do app StyledMap para ajudar você a criar um aplicativo semelhante.
Adicionar um recurso com um objeto de estilo JSON
Adicione um recurso ao projeto de desenvolvimento, contendo as declarações de estilo no formato JSON. É possível usar um recurso bruto ou uma string, como mostrado nos exemplos abaixo.
Defina um recurso bruto em /res/raw/style_json.json
com a declaração de estilo JSON para o estilo do modo noturno:
[
{
"featureType": "all",
"elementType": "geometry",
"stylers": [
{
"color": "#242f3e"
}
]
},
{
"featureType": "all",
"elementType": "labels.text.stroke",
"stylers": [
{
"lightness": -80
}
]
},
{
"featureType": "administrative",
"elementType": "labels.text.fill",
"stylers": [
{
"color": "#746855"
}
]
},
{
"featureType": "administrative.locality",
"elementType": "labels.text.fill",
"stylers": [
{
"color": "#d59563"
}
]
},
{
"featureType": "poi",
"elementType": "labels.text.fill",
"stylers": [
{
"color": "#d59563"
}
]
},
{
"featureType": "poi.park",
"elementType": "geometry",
"stylers": [
{
"color": "#263c3f"
}
]
},
{
"featureType": "poi.park",
"elementType": "labels.text.fill",
"stylers": [
{
"color": "#6b9a76"
}
]
},
{
"featureType": "road",
"elementType": "geometry.fill",
"stylers": [
{
"color": "#2b3544"
}
]
},
{
"featureType": "road",
"elementType": "labels.text.fill",
"stylers": [
{
"color": "#9ca5b3"
}
]
},
{
"featureType": "road.arterial",
"elementType": "geometry.fill",
"stylers": [
{
"color": "#38414e"
}
]
},
{
"featureType": "road.arterial",
"elementType": "geometry.stroke",
"stylers": [
{
"color": "#212a37"
}
]
},
{
"featureType": "road.highway",
"elementType": "geometry.fill",
"stylers": [
{
"color": "#746855"
}
]
},
{
"featureType": "road.highway",
"elementType": "geometry.stroke",
"stylers": [
{
"color": "#1f2835"
}
]
},
{
"featureType": "road.highway",
"elementType": "labels.text.fill",
"stylers": [
{
"color": "#f3d19c"
}
]
},
{
"featureType": "road.local",
"elementType": "geometry.fill",
"stylers": [
{
"color": "#38414e"
}
]
},
{
"featureType": "road.local",
"elementType": "geometry.stroke",
"stylers": [
{
"color": "#212a37"
}
]
},
{
"featureType": "transit",
"elementType": "geometry",
"stylers": [
{
"color": "#2f3948"
}
]
},
{
"featureType": "transit.station",
"elementType": "labels.text.fill",
"stylers": [
{
"color": "#d59563"
}
]
},
{
"featureType": "water",
"elementType": "geometry",
"stylers": [
{
"color": "#17263c"
}
]
},
{
"featureType": "water",
"elementType": "labels.text.fill",
"stylers": [
{
"color": "#515c6d"
}
]
},
{
"featureType": "water",
"elementType": "labels.text.stroke",
"stylers": [
{
"lightness": -20
}
]
}
]
Defina um recurso de string em /res/values/style_strings.xml
com a declaração de estilo do JSON para estilização do modo noturno. Este tutorial usa o nome de string style_json
. Nesse arquivo, você precisa usar uma barra invertida para fazer o escape das aspas:
<resources>
<string name="style_json">
[
{
\"featureType\": \"all\",
\"elementType\": \"geometry\",
\"stylers\": [
{
\"color\": \"#242f3e\"
}
]
},
{
\"featureType\": \"all\",
\"elementType\": \"labels.text.stroke\",
\"stylers\": [
{
\"lightness\": -80
}
]
},
{
\"featureType\": \"administrative\",
\"elementType\": \"labels.text.fill\",
\"stylers\": [
{
\"color\": \"#746855\"
}
]
},
{
\"featureType\": \"administrative.locality\",
\"elementType\": \"labels.text.fill\",
\"stylers\": [
{
\"color\": \"#d59563\"
}
]
},
{
\"featureType\": \"poi\",
\"elementType\": \"labels.text.fill\",
\"stylers\": [
{
\"color\": \"#d59563\"
}
]
},
{
\"featureType\": \"poi.park\",
\"elementType\": \"geometry\",
\"stylers\": [
{
\"color\": \"#263c3f\"
}
]
},
{
\"featureType\": \"poi.park\",
\"elementType\": \"labels.text.fill\",
\"stylers\": [
{
\"color\": \"#6b9a76\"
}
]
},
{
\"featureType\": \"road\",
\"elementType\": \"geometry.fill\",
\"stylers\": [
{
\"color\": \"#2b3544\"
}
]
},
{
\"featureType\": \"road\",
\"elementType\": \"labels.text.fill\",
\"stylers\": [
{
\"color\": \"#9ca5b3\"
}
]
},
{
\"featureType\": \"road.arterial\",
\"elementType\": \"geometry.fill\",
\"stylers\": [
{
\"color\": \"#38414e\"
}
]
},
{
\"featureType\": \"road.arterial\",
\"elementType\": \"geometry.stroke\",
\"stylers\": [
{
\"color\": \"#212a37\"
}
]
},
{
\"featureType\": \"road.highway\",
\"elementType\": \"geometry.fill\",
\"stylers\": [
{
\"color\": \"#746855\"
}
]
},
{
\"featureType\": \"road.highway\",
\"elementType\": \"geometry.stroke\",
\"stylers\": [
{
\"color\": \"#1f2835\"
}
]
},
{
\"featureType\": \"road.highway\",
\"elementType\": \"labels.text.fill\",
\"stylers\": [
{
\"color\": \"#f3d19c\"
}
]
},
{
\"featureType\": \"road.local\",
\"elementType\": \"geometry.fill\",
\"stylers\": [
{
\"color\": \"#38414e\"
}
]
},
{
\"featureType\": \"road.local\",
\"elementType\": \"geometry.stroke\",
\"stylers\": [
{
\"color\": \"#212a37\"
}
]
},
{
\"featureType\": \"transit\",
\"elementType\": \"geometry\",
\"stylers\": [
{
\"color\": \"#2f3948\"
}
]
},
{
\"featureType\": \"transit.station\",
\"elementType\": \"labels.text.fill\",
\"stylers\": [
{
\"color\": \"#d59563\"
}
]
},
{
\"featureType\": \"water\",
\"elementType\": \"geometry\",
\"stylers\": [
{
\"color\": \"#17263c\"
}
]
},
{
\"featureType\": \"water\",
\"elementType\": \"labels.text.fill\",
\"stylers\": [
{
\"color\": \"#515c6d\"
}
]
},
{
\"featureType\": \"water\",
\"elementType\": \"labels.text.stroke\",
\"stylers\": [
{
\"lightness\": -20
}
]
}
]
</string>
</resources>
Enviar um objeto de estilo JSON para seu mapa
Para personalizar seu mapa, chame GoogleMap.setMapStyle()
transmitindo um objeto MapStyleOptions
com suas declarações de estilo no formato JSON.
O exemplo de código a seguir supõe que seu projeto contenha um recurso bruto chamado 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)));
}
}
O layout (activity_maps_raw.xml
) tem esta aparência:
<!--
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.
-->
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.styledmap.MapsActivityRaw"
map:cameraZoom="10" />
O exemplo de código a seguir supõe que seu projeto tenha um recurso de string chamado 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)));
}
}
O layout (activity_maps_string.xml
) tem esta aparência:
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.styledmap.MapsActivityString"
map:cameraZoom="10" />
Mais informações sobre as declarações de estilo JSON
Os mapas estilizados usam dois conceitos para implementar cores e outras mudanças de estilo:
- Os seletores especificam os componentes geográficos que você pode personalizar no mapa. Por exemplo: vias, parques, corpos d'água e muito mais, bem como as etiquetas. Os seletores incluem recursos e elementos, especificados como propriedades
featureType
eelementType
. - Os estilizadores são propriedades de cor e visibilidade que você pode aplicar aos elementos do mapa. Eles definem a cor mostrada usando uma combinação de valores de matiz, cor e iluminação/gama.
Consulte a referência de estilo para conferir uma descrição detalhada das opções de estilo JSON.
Assistente de estilo da Plataforma Google Maps
Use o assistente de estilo da Plataforma Google Maps para gerar rapidamente um objeto de estilo JSON. O SDK do Maps para Android é compatível com as mesmas declarações de estilo da API Maps JavaScript.
Próxima etapa
Saiba como ocultar recursos no mapa com estilos.