Objetos "map"

Os mapas são representados na API pelas classes GoogleMap e SupportMapFragment.

Adicionar um mapa a um app para Android

Veja como adicionar um mapa:

  1. Só é necessário concluir esta etapa uma vez. Siga as instruções do guia de configuração do projeto para definir a chave de API e as dependências do Gradle.
  2. Adicione um objeto Fragment à Activity que lidará com o mapa. A maneira mais fácil de fazer isso é incluir um elemento <fragment> no arquivo de layout da Activity.
  3. Implemente a interface OnMapReadyCallback e use o método de callback onMapReady(GoogleMap) para aplicar um identificador ao objeto GoogleMap. O objeto GoogleMap é a representação interna do próprio mapa. Para definir as opções de visualização de um mapa, é preciso modificar o objeto GoogleMap dele.
  4. Chame getMapAsync() no fragmento para registrar o callback.

Veja a seguir mais detalhes sobre cada etapa.

Adicionar um fragmento

Inclua um elemento <fragment> no arquivo de layout da atividade para configurar um objeto Fragment. Nesse elemento, defina o atributo android:name como "com.google.android.gms.maps.SupportMapFragment. Isso anexará automaticamente um SupportMapFragment à atividade.

O arquivo de layout a seguir contém um elemento <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.SupportMapFragment"
    android:id="@+id/map"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

Você também pode adicionar um SupportMapFragment a uma Activity no código. Para fazer isso, crie uma nova instância SupportMapFragment e, depois, chame FragmentTransaction.add() para incluir o Fragment na Activity atual.

Java

SupportMapFragment mapFragment = SupportMapFragment.newInstance();
getSupportFragmentManager()
    .beginTransaction()
    .add(R.id.my_container, mapFragment)
    .commit();
      

Kotlin

val mapFragment = SupportMapFragment.newInstance()
supportFragmentManager
    .beginTransaction()
    .add(R.id.my_container, mapFragment)
    .commit()
      

Adicionar código do mapa

Para trabalhar com o mapa no seu app, implemente a interface OnMapReadyCallback e defina uma instância do callback em um objeto SupportMapFragment ou MapView. Neste tutorial, usamos SupportMapFragment, porque essa é a maneira mais comum de adicionar um mapa a um app. A primeira etapa é implementar a interface de callback:

Java

class MainActivity extends AppCompatActivity implements OnMapReadyCallback {
    // ...
}
      

Kotlin

class MainActivity : AppCompatActivity(), OnMapReadyCallback {

    // ...
}
      

No método onCreate() da Activity, defina o arquivo de layout como a visualização de conteúdo. Por exemplo, se o arquivo tiver o nome main.xml, use este código:

Java

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
}
      

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.main)
}
      

Receba um identificador para o fragmento ao chamar FragmentManager.findFragmentById() e transmitir o ID do recurso do seu elemento <fragment>. O ID R.id.map será adicionado automaticamente ao projeto Android quando você criar o arquivo de layout.

Depois, use getMapAsync() para definir o callback no fragmento.

Java

SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
    .findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
      

Kotlin

val mapFragment = supportFragmentManager
    .findFragmentById(R.id.map) as SupportMapFragment
mapFragment.getMapAsync(this)
      

Use o método de callback onMapReady(GoogleMap) se quiser receber um identificador para o objeto GoogleMap. O callback será acionado quando o mapa estiver pronto para ser utilizado. Ele fornece uma instância não nula de GoogleMap. Você pode usar o objeto GoogleMap para, por exemplo, definir as opções de visualização do mapa ou adicionar um marcador.

Java

@Override
public void onMapReady(GoogleMap googleMap) {
    googleMap.addMarker(new MarkerOptions()
        .position(new LatLng(0, 0))
        .title("Marker"));
}
      

Kotlin

override fun onMapReady(googleMap: GoogleMap) {
    googleMap.addMarker(
        MarkerOptions()
            .position(LatLng(0.0, 0.0))
            .title("Marker")
    )
}
      

Objeto "map"

Com o Maps SDK for Android, você pode exibir um mapa do Google no seu aplicativo para Android. Esses mapas têm a mesma aparência que aqueles no app Google Maps para dispositivos móveis (GMM, na sigla em inglês), e a API expõe muitos dos mesmos elementos. Confira duas diferenças consideráveis entre o aplicativo GMM e os mapas exibidos pelo Maps SDK for Android:

  • Os blocos de mapa exibidos pela API não apresentam conteúdo personalizado, como ícones inteligentes personalizados.
  • Nem todos os ícones no mapa são clicáveis. Por exemplo, não é possível clicar em ícones de estação de transporte público. No entanto, os marcadores adicionados ao mapa são clicáveis, e a API tem uma interface de callback de listener para diversas interações com marcador.

Além do mapeamento, a API também aceita várias interações semelhantes ao modelo de IU do Android. Por exemplo, você pode configurar as interações com um mapa definindo listeners que respondem a gestos do usuário.

A classe mais importante ao trabalhar com um objeto "map" é GoogleMap. GoogleMap modela o objeto "map" no seu aplicativo. Na IU, um mapa será representado por um objeto SupportMapFragment ou MapView.

GoogleMap lida com as seguintes operações automaticamente:

  • Conexão com o serviço do Google Maps
  • Download de blocos de mapas
  • Exibição de blocos na tela do dispositivo
  • Exibição de vários controles, como panorâmica e zoom
  • Resposta aos gestos de movimento e de zoom, deslocando o mapa e aumentando ou diminuindo o zoom

Além dessas operações automáticas, você pode controlar o comportamento dos mapas com objetos e métodos da API. Por exemplo, GoogleMap tem métodos de callback que respondem a toques de tela e gestos de toque. Também é possível definir ícones de marcador no seu mapa e adicionar sobreposições a ele usando os objetos definidos para GoogleMap.

SupportMapFragment

SupportMapFragment, uma subclasse de Fragment do Android, permite que você insira um mapa em um fragmento do Android. Os objetos SupportMapFragment atuam como contêineres e dão acesso ao GoogleMap.

Ao contrário de um objeto View, um Fragment representa um comportamento ou parte da interface do usuário em uma atividade. Você pode combinar vários fragmentos em uma única atividade para criar uma IU de vários painéis e reutilizar um fragmento em diversas atividades. Consulte a documentação de fragmentos do Android para saber mais.

MapView

MapView, uma subclasse de View do Android, permite que você insira um mapa em uma View do Android. Uma View representa uma região retangular da tela e é fundamental para os apps e widgets Android. Assim como um SupportMapFragment, a MapView atua como um contêiner que mostra funcionalidades importantes do mapa usando o objeto GoogleMap.

Ao utilizar a API no modo totalmente interativo, a classe MapView precisa encaminhar os seguintes métodos de ciclo da atividade aos métodos correspondentes da MapView: onCreate(), onStart(), onResume(), onPause(), onStop(), onDestroy(), onSaveInstanceState() e onLowMemory(). O repositório ApiDemos no GitHub inclui um exemplo (Java / Kotlin) que demonstra como encaminhar os métodos de ciclo de vida da atividade. Ao usar a API no Modo Lite, o encaminhamento dos eventos de ciclo de vida é opcional. Para ver detalhes, consulte a documentação relacionada.

Tipos de mapa

Há muitos tipos de mapa disponíveis no Maps SDK for Android, que controlam a representação geral do mapa. Por exemplo, um atlas geralmente contém mapas políticos que mostram fronteiras e mapas rodoviários que incluem todas as vias de uma cidade ou região.

O Maps SDK for Android oferece quatro tipos de mapa, além de uma opção para não exibir nenhuma representação visual.

Normal
Mapa rodoviário comum. Mostra vias, alguns elementos criados pelo homem e recursos naturais importantes, como rios. Etiquetas de estradas e de elementos também são visíveis.
Híbrido
Dados de fotografia de satélite com mapas rodoviários. Etiquetas de estradas e de elementos também são visíveis.
Satélite
Dados de fotografia de satélite. Marcadores de estradas e de elementos não são visíveis.
Relevo
Dados topográficos. O mapa inclui cores, curvas de nível e etiquetas, além de sombreamento de perspectiva. Algumas vias e etiquetas também são visíveis.
Nenhum
Nenhum bloco. O mapa será renderizado como uma grade vazia, sem carregar blocos.

Alterar o tipo de mapa

Para configurar o tipo de um mapa, chame o método setMapType() do objeto GoogleMap, transferindo uma das constantes de tipo definidas em GoogleMap. Por exemplo, para exibir um mapa de satélite:

Java

// Sets the map type to be "hybrid"
map.setMapType(GoogleMap.MAP_TYPE_HYBRID);
      

Kotlin

// Sets the map type to be "hybrid"
map.mapType = GoogleMap.MAP_TYPE_HYBRID
      

A imagem abaixo mostra uma comparação entre mapas normais, híbridos e de terreno para o mesmo local:

Comparação de MapType

Mapas internos

O mapa mostra, em níveis altos de zoom, plantas baixas para espaços internos, como aeroportos, shoppings, grandes lojas de varejo e estações de transporte público. Essas plantas, chamadas de mapas internos, são exibidas para os tipos de mapa "Normal" e "Satélite" (GoogleMap.MAP_TYPE_NORMAL e GoogleMap.MAP_TYPE_SATELLITE). Elas são ativadas automaticamente quando o usuário aumenta o zoom e desaparecem quando ele é reduzido.

Aviso de suspensão de uso: em uma versão futura, os mapas internos só estarão disponíveis no tipo de mapa normal. A partir dela, esses mapas não serão compatíveis com satellite, terrain ou hybrid. Mesmo quando o modo interno não for aceito, isIndoorEnabled() continuará retornando o valor definido usando setIndoorEnabled(), como já acontece. Por padrão, setIndoorEnabled é true. As notas da versão informarão quando o suporte ao modo interno ficar indisponível nesses tipos de mapa.

Exemplo de mapa interno

Trabalhar com mapas internos na API

Veja a seguir um resumo da funcionalidade dos mapas internos na API:

A estilização do mapa básico não afeta os mapas internos.

Adicionar plantas baixas

Os mapas internos (plantas baixas) estão disponíveis em locais específicos. Se não houver dados de planta baixa para um edifício que você quer destacar no seu app, será possível:

Camada de trânsito

Você pode permitir que os usuários visualizem o mapa com informações de densidade de trânsito sobrepostas. Com isso, eles terão acesso a um resumo visual da situação do trânsito local. É possível ativar ou desativar a camada de trânsito chamando o método setTrafficEnabled(). Para saber se ela está habilitada, chame isTrafficEnabled(). O exemplo a seguir mostra como a camada de tráfego pode aparecer em um mapa.

Um mapa do Google mostrando a camada de trânsito

Configurar o estado inicial

Com a API Maps, você pode configurar o estado inicial do mapa para atender às necessidades do seu aplicativo. É possível especificar o seguinte:

  • A posição da câmera, incluindo localização, zoom, direção e inclinação. Consulte Câmera e visualização para mais detalhes sobre o posicionamento da câmera.
  • O tipo de mapa.
  • Se os botões do zoom e/ou da bússola aparecem na tela.
  • Os gestos que um usuário pode usar para manipular a câmera.
  • Se o Modo Lite está ativado ou não. Um mapa no Modo Lite é uma imagem em bitmap de um mapa que oferece suporte a um subconjunto das funções oferecidas pela API completa.

Você pode configurar o estado inicial por XML, se tiver adicionado o mapa ao arquivo de layout da sua atividade, ou de modo programático, se tiver incluído o mapa dessa maneira.

Como usar atributos XML

Nesta seção, descrevemos como definir o estado inicial se você tiver adicionado um mapa ao seu app usando um arquivo de layout XML.

A API Maps define um conjunto de atributos XML personalizados para um SupportMapFragment ou MapView que você pode usar para configurar o estado inicial diretamente do arquivo de layout. Os seguintes atributos estão definidos no momento:

  • mapType. Permite especificar o tipo de mapa que será exibido. Os valores válidos incluem: none, normal, hybrid, satellite e terrain.
  • cameraTargetLat, cameraTargetLng, cameraZoom, cameraBearing, cameraTilt. Permitem especificar a posição inicial da câmera. Veja mais detalhes sobre a posição da câmera e as propriedades dela.
  • uiZoomControls, uiCompass. Permitem definir se os controles de zoom e a bússola aparecerão no mapa. Consulte UiSettings para ver mais detalhes.
  • uiZoomGestures, uiScrollGestures, uiRotateGestures, uiTiltGestures. Permitem especificar quais gestos podem ser usados para interagir com o mapa. Consulte UiSettings para ver mais detalhes.
  • zOrderOnTop: controla se a superfície da visualização de mapa será posicionada sobre a janela. Consulte SurfaceView.setZOrderOnTop(boolean) para mais detalhes. Esse item abrange todas as outras visualizações que podem aparecer no mapa (por exemplo, os controles de zoom, o botão "Meu local").
  • useViewLifecycle: só é válido com um SupportMapFragment. Esse atributo especifica se o ciclo de vida do mapa deve ser vinculado à visualização do fragmento ou ao próprio fragmento. Consulte este link para ver mais detalhes.
  • liteMode: um valor true altera o mapa para o Modo Lite. Um mapa no Modo Lite é uma imagem em bitmap que oferece suporte a um subconjunto das funções oferecidas pela API completa. O valor padrão desse atributo é false.

Para usar esses atributos personalizados no seu arquivo de layout XML, adicione primeiro a seguinte declaração de namespace. Você pode escolher qualquer namespace (não precisa ser map):

xmlns:map="http://schemas.android.com/apk/res-auto"

Em seguida, é possível incluir os atributos com um prefixo map: nos componentes do layout, como você faria com os atributos padrão do Android.

O snippet de código XML a seguir mostra como configurar um SupportMapFragment com algumas opções personalizadas. Os mesmos atributos podem ser aplicados a uma 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"/>

De forma programática

Nesta seção, explicamos como definir o estado inicial se você tiver adicionado um mapa ao seu app de maneira programática.

Se você tiver incluído SupportMapFragment (ou MapView) de forma programática, poderá configurar o estado inicial transmitindo um objeto GoogleMapOptions com as opções especificadas. As opções disponíveis são as mesmas do XML. Você pode criar um objeto GoogleMapOptions como este:

Java

GoogleMapOptions options = new GoogleMapOptions();
      

Kotlin

val options = GoogleMapOptions()
      

E configurá-lo da seguinte forma:

Java

options.mapType(GoogleMap.MAP_TYPE_SATELLITE)
    .compassEnabled(false)
    .rotateGesturesEnabled(false)
    .tiltGesturesEnabled(false);
      

Kotlin

options.mapType(GoogleMap.MAP_TYPE_SATELLITE)
    .compassEnabled(false)
    .rotateGesturesEnabled(false)
    .tiltGesturesEnabled(false)
      

Para aplicar essas opções durante a criação do mapa, realize uma das seguintes ações:

Padding do mapa

Este vídeo mostra um exemplo de padding do mapa.

Um mapa do Google precisa preencher toda a região definida pelo elemento do contêiner (normalmente uma MapView ou um SupportMapFragment). Vários aspectos da exibição e do comportamento de um mapa são definidos pelas dimensões do contêiner:

  • A alvo da câmera será o centro da região preenchida.
  • Os controles do mapa são posicionados em relação às margens dele.
  • Informações legais, como declarações de direitos autorais ou o logotipo do Google, aparecem na margem inferior.

Para adicionar padding ao redor das margens do mapa, use o método GoogleMap.setPadding(). O mapa continuará preenchendo todo o contêiner, mas o posicionamento do texto e dos controles, os gestos do mapa e os movimentos da câmera responderão como se estivessem em um espaço menor. Isso resulta nas seguintes alterações:

  • Os movimentos da câmera por meio de chamadas de API ou pressionamento de botões (por exemplo, botões da bússola, de zoom ou "Meu local") serão relativos à região preenchida.
  • getCameraPosition() retornará o centro da região preenchida.
  • Projection.getVisibleRegion() retornará a região preenchida.
  • O controles de IU serão deslocados da margem do contêiner pelo número especificado de pixels.

O padding pode ser útil ao criar IUs que se sobrepõem a uma parte do mapa. Por exemplo, na imagem inferior, o mapa é preenchido nas margens superior e direita. Controles de mapa e texto legal visíveis são exibidos nas margens da região preenchida, em verde, enquanto o mapa continua preenchendo o contêiner inteiro, mostrado em azul. Nesse exemplo, você poderia exibir um menu flutuante no lado direito, sem ocultar os controles.

Padding do mapa

Localizar seu mapa

Quando você adiciona uma MapView ou um SupportMapFragment ao app, os elementos textuais do mapa são exibidos no idioma apropriado com base nas configurações do dispositivo e no local do usuário. É possível restringir os idiomas utilizados pelo aplicativo a um subconjunto de todos os idiomas compatíveis. Basta adicionar um item resConfigs ao seu arquivo do Gradle. Isso é útil para remover idiomas não utilizados e reduzir o tamanho binário do seu app. Exemplo:

defaultConfig {
    resConfigs "en", "fr", "es", "zh", "de", "ja", "ru", "ko", "pt", "in"
}

Saiba como localizar seu app para Android.