Os marcadores indicam locais únicos no mapa. Você pode personalizar um marcador alterando a cor padrão ou substituindo o ícone dele por uma imagem personalizada. As janelas de informações dão mais contexto para um marcador.
Exemplos de código
O repositório ApiDemos (link em inglês) no GitHub inclui um exemplo que demonstra vários recursos de marcadores:
Kotlin
- MapWithMarker: um mapa simples com um marcador. Veja o tutorial sobre como adicionar um mapa com um marcador.
- MarkerDemoActivity: usar marcadores em um mapa, incluindo opções e listeners.
Java
- MapWithMarker: um mapa simples com um marcador. Veja o tutorial sobre como adicionar um mapa com um marcador.
- MarkerDemoActivity: usar marcadores em um mapa, incluindo opções e listeners.
Introdução
Os marcadores identificam locais no mapa. O marcador padrão usa um ícone comum, parecido com o do Google Maps. É possível mudar a cor, a imagem ou o ponto de fixação do ícone usando a API. Os marcadores são objetos do tipo Marker
e são adicionados ao mapa com o método GoogleMap.addMarker(markerOptions)
.
Eles foram criados para serem interativos. Por padrão, recebem eventos de click
e costumam ser usados com listeners relacionados para exibir janelas de informações. Definir a propriedade draggable
de um marcador como true
permite alterar a posição dele. Toque e mantenha o marcador pressionado para movê-lo.
Por padrão, quando um usuário toca em um marcador, a barra de ferramentas do mapa aparece no canto inferior direito, dando ao usuário acesso rápido ao app Google Maps. É possível desativar essa barra. Para mais informações, consulte o guia sobre os controles.
Como começar a usar marcadores
Este episódio do Maps Live aborda os conceitos básicos sobre a adição de marcadores ao mapa usando o SDK do Maps para Android.
Adicionar um marcador
O exemplo a seguir demonstra como incluir um marcador no mapa. O marcador é criado nas coordenadas -33.852,151.211
(Sydney, Austrália) e mostra a string "Marker in Sydney" em uma janela de informações quando alguém clica nele.
Kotlin
override fun onMapReady(googleMap: GoogleMap) { // Add a marker in Sydney, Australia, // and move the map's camera to the same location. val sydney = LatLng(-33.852, 151.211) googleMap.addMarker( MarkerOptions() .position(sydney) .title("Marker in Sydney") ) googleMap.moveCamera(CameraUpdateFactory.newLatLng(sydney)) }
Java
@Override public void onMapReady(GoogleMap googleMap) { // Add a marker in Sydney, Australia, // and move the map's camera to the same location. LatLng sydney = new LatLng(-33.852, 151.211); googleMap.addMarker(new MarkerOptions() .position(sydney) .title("Marker in Sydney")); googleMap.moveCamera(CameraUpdateFactory.newLatLng(sydney)); }
Exibir mais informações sobre um marcador
Um requisito comum é mostrar mais informações sobre um lugar ou uma região quando o usuário toca em um marcador no mapa. Consulte o guia sobre janelas de informações.
Associar dados a um marcador
É possível armazenar um objeto de dados arbitrários com um marcador usando Marker.setTag()
e recuperar esse objeto com Marker.getTag()
. O exemplo abaixo mostra como você pode contar o número de cliques em um marcador usando tags:
Kotlin
/** * A demo class that stores and retrieves data objects with each marker. */ class MarkerDemoActivity : AppCompatActivity(), OnMarkerClickListener, OnMapReadyCallback { private val PERTH = LatLng(-31.952854, 115.857342) private val SYDNEY = LatLng(-33.87365, 151.20689) private val BRISBANE = LatLng(-27.47093, 153.0235) private var markerPerth: Marker? = null private var markerSydney: Marker? = null private var markerBrisbane: Marker? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_markers) val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment? mapFragment!!.getMapAsync(this) } /** Called when the map is ready. */ override fun onMapReady(map: GoogleMap) { // Add some markers to the map, and add a data object to each marker. markerPerth = map.addMarker( MarkerOptions() .position(PERTH) .title("Perth") ) markerPerth?.tag = 0 markerSydney = map.addMarker( MarkerOptions() .position(SYDNEY) .title("Sydney") ) markerSydney?.tag = 0 markerBrisbane = map.addMarker( MarkerOptions() .position(BRISBANE) .title("Brisbane") ) markerBrisbane?.tag = 0 // Set a listener for marker click. map.setOnMarkerClickListener(this) } /** Called when the user clicks a marker. */ override fun onMarkerClick(marker: Marker): Boolean { // Retrieve the data from the marker. val clickCount = marker.tag as? Int // Check if a click count was set, then display the click count. clickCount?.let { val newClickCount = it + 1 marker.tag = newClickCount Toast.makeText( this, "${marker.title} has been clicked $newClickCount times.", Toast.LENGTH_SHORT ).show() } // Return false to indicate that we have not consumed the event and that we wish // for the default behavior to occur (which is for the camera to move such that the // marker is centered and for the marker's info window to open, if it has one). return false } }
Java
/** * A demo class that stores and retrieves data objects with each marker. */ public class MarkerDemoActivity extends AppCompatActivity implements GoogleMap.OnMarkerClickListener, OnMapReadyCallback { private final LatLng PERTH = new LatLng(-31.952854, 115.857342); private final LatLng SYDNEY = new LatLng(-33.87365, 151.20689); private final LatLng BRISBANE = new LatLng(-27.47093, 153.0235); private Marker markerPerth; private Marker markerSydney; private Marker markerBrisbane; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_markers); SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map); mapFragment.getMapAsync(this); } /** Called when the map is ready. */ @Override public void onMapReady(GoogleMap map) { // Add some markers to the map, and add a data object to each marker. markerPerth = map.addMarker(new MarkerOptions() .position(PERTH) .title("Perth")); markerPerth.setTag(0); markerSydney = map.addMarker(new MarkerOptions() .position(SYDNEY) .title("Sydney")); markerSydney.setTag(0); markerBrisbane = map.addMarker(new MarkerOptions() .position(BRISBANE) .title("Brisbane")); markerBrisbane.setTag(0); // Set a listener for marker click. map.setOnMarkerClickListener(this); } /** Called when the user clicks a marker. */ @Override public boolean onMarkerClick(final Marker marker) { // Retrieve the data from the marker. Integer clickCount = (Integer) marker.getTag(); // Check if a click count was set, then display the click count. if (clickCount != null) { clickCount = clickCount + 1; marker.setTag(clickCount); Toast.makeText(this, marker.getTitle() + " has been clicked " + clickCount + " times.", Toast.LENGTH_SHORT).show(); } // Return false to indicate that we have not consumed the event and that we wish // for the default behavior to occur (which is for the camera to move such that the // marker is centered and for the marker's info window to open, if it has one). return false; } }
Confira alguns exemplos de situações em que é útil armazenar e recuperar informações com marcadores:
- Seu app pode oferecer vários tipos de marcador, e é útil dar um tratamento diferente a cada um quando o usuário clicar neles. Para fazer isso, armazene uma
String
com o marcador indicando o tipo. - É possível que você interaja com um sistema que tem identificadores de registros exclusivos, em que os marcadores representam registros específicos.
- Os dados do marcador podem indicar uma prioridade que será usada ao decidir o Z-index dele.
Tornar um marcador arrastável
Você pode reposicionar um marcador depois que ele é adicionado ao mapa, desde que a propriedade draggable
esteja definida como true
. Toque e mantenha o marcador pressionado para arrastar. Quando você tira o dedo da tela, o elemento permanece na mesma posição.
Por padrão, os marcadores não são arrastáveis. É preciso definir explicitamente o marcador como arrastável com MarkerOptions.draggable(boolean)
antes de adicionar ao mapa ou com Marker.setDraggable(boolean)
depois da inclusão.
Você pode detectar eventos de arrastar no elemento, conforme descrito na seção relacionada.
Com o snippet a seguir, é possível adicionar um marcador arrastável em Perth, Austrália.
Kotlin
val perthLocation = LatLng(-31.90, 115.86) val perth = map.addMarker( MarkerOptions() .position(perthLocation) .draggable(true) )
Java
final LatLng perthLocation = new LatLng(-31.90, 115.86); Marker perth = map.addMarker( new MarkerOptions() .position(perthLocation) .draggable(true));
Personalizar um marcador
Esse vídeo mostra formas de usar marcadores para visualizar locais em um mapa.
Os marcadores podem definir uma imagem personalizada que será exibida no lugar do ícone padrão. A definição de um ícone envolve a configuração de várias propriedades que afetam a aparência do elemento.
É possível editar os marcadores com estas propriedades:
- Position (obrigatória)
- O valor
LatLng
para a posição do marcador no mapa. Essa é a única propriedade obrigatória para um objetoMarker
. - Anchor
- O ponto na imagem que será colocado na posição LatLng do marcador. Por padrão, a parte central inferior da imagem.
- Alpha
- Define a opacidade do marcador. O padrão é 1.0.
- Title
- Uma string que é mostrada na janela de informações quando o usuário toca no marcador.
- Snippet
- O texto adicional que é exibido abaixo do título.
- Icon
- Um bitmap que aparece no lugar da imagem do marcador padrão.
- Draggable
- Defina como
true
se você quiser permitir que o usuário mova o marcador. Por padrão, é configurado comofalse
. - Visible
- Defina como
false
para tornar o marcador invisível. Por padrão, é configurado comotrue
. - Orientação plana ou de outdoor (Flat ou Billboard)
- Por padrão, os marcadores usam uma orientação de outdoor, então sua forma acompanha a tela do dispositivo, e não a superfície do mapa. A orientação do marcador não muda mesmo se a pessoa gira ou inclina o aparelho ou se muda o zoom do mapa. Você pode definir a orientação de um marcador como plana em relação ao solo. Marcadores planos mudam quando o mapa é girado e apresentam outra perspectiva quando o mapa é inclinado. Tanto os marcadores de outdoor quanto os planos não mudam de tamanho quando o zoom no mapa aumenta ou diminui.
- Rotation
- A orientação do marcador, especificada em graus no sentido horário. A posição padrão muda quando o marcador é plano. A posição padrão de um marcador plano é alinhada ao norte. Quando o marcador não é plano, a posição padrão aponta para cima, e a rotação deixa o marcador sempre de frente para a câmera.
O snippet abaixo cria um marcador simples com o ícone padrão.
Kotlin
val melbourneLocation = LatLng(-37.813, 144.962) val melbourne = map.addMarker( MarkerOptions() .position(melbourneLocation) )
Java
final LatLng melbourneLocation = new LatLng(-37.813, 144.962); Marker melbourne = map.addMarker( new MarkerOptions() .position(melbourneLocation));
Personalizar a cor do marcador
Se quiser personalizar a cor da imagem do marcador padrão, transmita um objeto BitmapDescriptor
para o método icon(). Você pode usar um conjunto de cores predefinidas no objeto BitmapDescriptorFactory
ou definir uma cor personalizada com o método BitmapDescriptorFactory.defaultMarker(float hue)
. A tonalidade é um valor entre 0 e 360, representando pontos em uma paleta de cores.
Kotlin
val melbourneLocation = LatLng(-37.813, 144.962) val melbourne = map.addMarker( MarkerOptions() .position(melbourneLocation) .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE)) )
Java
final LatLng melbourneLocation = new LatLng(-37.813, 144.962); Marker melbourne = map.addMarker( new MarkerOptions() .position(melbourneLocation) .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE)));
Personalizar a opacidade do marcador
Você pode controlar a opacidade de um marcador com o método MarkerOptions.alpha(). "Alpha" precisa ser especificado como um ponto flutuante entre 0 e 1, em que 0 é totalmente transparente, e 1 é todo opaco.
Kotlin
val melbourneLocation = LatLng(-37.813, 144.962) val melbourne = map.addMarker( MarkerOptions() .position(melbourneLocation) .alpha(0.7f) )
Java
final LatLng melbourneLocation = new LatLng(-37.813, 144.962); Marker melbourne = map.addMarker(new MarkerOptions() .position(melbourneLocation) .alpha(0.7f));
Personalizar a imagem do marcador
Você pode substituir a imagem padrão do marcador por uma personalizada, muitas vezes chamada de ícone. Ícones personalizados são sempre definidos como BitmapDescriptor
usando um dos métodos na classe BitmapDescriptorFactory
.
fromAsset(String assetName)
- Cria um marcador personalizado utilizando o nome de uma imagem em bitmap no diretório de assets.
fromBitmap(Bitmap image)
- Cria um marcador personalizado diretamente de uma imagem em bitmap.
fromFile(String fileName)
- Cria um ícone personalizado usando o nome de um arquivo de imagem em bitmap localizado no armazenamento interno.
fromPath(String absolutePath)
- Cria um marcador personalizado diretamente de um caminho de arquivo absoluto de uma imagem em bitmap.
fromResource(int resourceId)
- Cria um marcador personalizado usando o ID do recurso de uma imagem em bitmap.
O snippet abaixo cria um marcador com um ícone personalizado.
Kotlin
val melbourneLocation = LatLng(-37.813, 144.962) val melbourne = map.addMarker( MarkerOptions() .position(melbourneLocation) .title("Melbourne") .snippet("Population: 4,137,400") .icon(BitmapDescriptorFactory.fromResource(R.drawable.arrow)) )
Java
final LatLng melbourneLocation = new LatLng(-37.813, 144.962); Marker melbourne = map.addMarker( new MarkerOptions() .position(melbourneLocation) .title("Melbourne") .snippet("Population: 4,137,400") .icon(BitmapDescriptorFactory.fromResource(R.drawable.arrow)));
Nivelar um marcador
Normalmente, os ícones de marcadores são posicionados em relação à tela. Girar, inclinar ou alterar o zoom do mapa não altera a orientação do marcador. Você pode definir a orientação como plana em relação à Terra. Dessa forma, os marcadores vão girar quando o mapa também for girado e mudar de perspectiva quando ele for inclinado. Os marcadores planos não mudam de tamanho quando o mapa é ampliado ou reduzido.
Para alterar a orientação do marcador, defina a propriedade flat
como true
.
Kotlin
val perthLocation = LatLng(-31.90, 115.86) val perth = map.addMarker( MarkerOptions() .position(perthLocation) .flat(true) )
Java
final LatLng perthLocation = new LatLng(-31.90, 115.86); Marker perth = map.addMarker( new MarkerOptions() .position(perthLocation) .flat(true));
Girar um marcador
Você pode girar um marcador em torno do ponto de fixação dele com o método Marker
.setRotation()
. A rotação é medida em graus no sentido horário a partir da posição padrão. Quando o marcador é plano no mapa, esse padrão é o norte. Quando ele não é plano, a posição padrão aponta para cima, e a rotação o coloca sempre de frente para a câmera.
O exemplo abaixo gira o marcador em 90°. Definir o ponto de fixação como 0.5,0.5
faz com que o marcador seja girado em torno do próprio centro, em vez da base.
Kotlin
val perthLocation = LatLng(-31.90, 115.86) val perth = map.addMarker( MarkerOptions() .position(perthLocation) .anchor(0.5f, 0.5f) .rotation(90.0f) )
Java
final LatLng perthLocation = new LatLng(-31.90, 115.86); Marker perth = map.addMarker( new MarkerOptions() .position(perthLocation) .anchor(0.5f,0.5f) .rotation(90.0f));
Z-index do marcador
O Z-index especifica a ordem de empilhamento desse marcador em relação a outros no mapa. Um marcador com um Z-index alto tem prioridade sobre aqueles com valores menores. O valor padrão do Z-index é 0
.
Para definir o Z-index no objeto de opções do marcador, chame MarkerOptions.zIndex()
, conforme o snippet de código a seguir:
Kotlin
map.addMarker( MarkerOptions() .position(LatLng(10.0, 10.0)) .title("Marker z1") .zIndex(1.0f) )
Java
map.addMarker(new MarkerOptions() .position(new LatLng(10, 10)) .title("Marker z1") .zIndex(1.0f));
Você pode acessar o Z-index do marcador chamando Marker.getZIndex()
. Se quiser alterá-lo, invoque Marker.setZIndex()
.
Os marcadores são sempre colocados acima das camadas de blocos e de outras sobreposições que não são marcadores (sobreposições de solo, polilinhas, polígonos e outras formas), independentemente do Z-index das outras sobreposições. Considera-se que os marcadores estão em um grupo de Z-index diferente de outras sobreposições.
Leia abaixo sobre o efeito do Z-index em eventos de clique.
Gerenciar eventos de marcador
Com a API Maps, você pode detectar e responder a eventos de marcador. Para detectar esses eventos, defina o listener correspondente no objeto GoogleMap
a que os marcadores pertencem. Quando o evento ocorrer em um dos marcadores no mapa, o callback do listener será invocado com o objeto Marker
correspondente, transmitido como um parâmetro. Para comparar esse objeto Marker
com sua própria referência a um objeto Marker
, use equals()
e não ==
.
É possível detectar os seguintes eventos:
- Eventos de clique no marcador
- Eventos de arrastar o marcador
- Eventos de clique na janela de informações
Eventos de clique no marcador
Você pode usar um OnMarkerClickListener
para detectar eventos de clique no marcador. Se quiser definir esse listener no mapa, chame GoogleMap.setOnMarkerClickListener(OnMarkerClickListener)
. Quando um usuário clica em um marcador, onMarkerClick(Marker)
é chamado, e o marcador é transmitido como um argumento. Esse método retorna um booleano que indica se você consumiu o evento, ou seja, quer suprimir o comportamento padrão. Se ele retornar false
, o comportamento padrão e o personalizado ocorrerão. Por padrão, o evento de clique mostra a janela de informações (se disponível), e a câmera posiciona o marcador no centro do mapa.
Efeito do Z-index em eventos de clique:
- Quando um usuário clica em um cluster de marcadores, o evento de clique é acionado para aquele que tem o maior Z-index.
- Só é possível acionar um evento por clique. Em outras palavras, o clique não é transmitido para os marcadores ou outras sobreposições com valores menores de Z-index.
- Clicar em um cluster de marcadores faz com que os próximos cliques passem pelo cluster, selecionando um por vez. A ordem do ciclo prioriza o Z-index e, em seguida, a proximidade ao ponto de clique.
- Se o usuário clica longe do cluster, a API recalcula o conjunto e redefine o estado do ciclo de clique para que comece do início.
- O evento de clique passa dos clusters de marcadores para outras formas e sobreposições antes de reiniciar o ciclo.
- Considera-se que os marcadores estão em um grupo Z-index diferente de outras sobreposições ou formas (polilinhas, polígonos, círculos e/ou sobreposições de solo), independentemente do Z-index das outras sobreposições. Se vários marcadores, sobreposições ou formas forem sobrepostos entre si, o evento de clique passará pelo cluster de marcadores primeiro e, depois, será acionado por outras sobreposições ou formas clicáveis com base nos valores Z-index delas.
Eventos de arrastar o marcador
Você pode usar um OnMarkerDragListener
para detectar eventos de arrastar em um marcador. Se quiser definir esse listener no mapa, chame GoogleMap.setOnMarkerDragListener
. Para arrastar um marcador, o usuário precisa tocar nele e mantê-lo pressionado. Quando o usuário tira o dedo da tela, o elemento fica na mesma posição. Quando um marcador é arrastado, onMarkerDragStart(Marker)
é chamado primeiro. onMarkerDrag(Marker)
é invocado enquanto o elemento está sendo arrastado. No final da ação, onMarkerDragEnd(Marker)
é chamado. Para ver a posição do marcador a qualquer momento, invoque Marker.getPosition()
.