É o 15º aniversário da Plataforma Google Maps: confira as notícias e avisos mais recentes

Marcadores

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.

Amostras de código

O repositório ApiDemos no GitHub inclui um exemplo que demonstra vários elementos de marcador:

Introdução

Os marcadores identificam locais no mapa. O marcador padrão usa um ícone padrão, parecido com o do Google Maps. É possível alterar a cor, a imagem ou o ponto de fixação do ícone utilizando a API. Os marcadores são objetos do tipo Marker e são adicionados ao mapa com o método GoogleMap.addMarker(markerOptions).

Os marcadores foram projetados para serem interativos. Por padrão, eles 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. Use um toque longo para poder mover o marcador.

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.

Primeiros passos com os marcadores

Este episódio do Maps Live aborda os conceitos básicos sobre a adição de marcadores ao mapa usando o Maps SDK for Android.

Adicionar um marcador

O exemplo a seguir demonstra como incluir um marcador no mapa. O marcador é criado nas coordenadas 10,10 e exibe a string "Hello world" (Olá, mundo) em uma janela de informações quando alguém clica nele.

@Override
public void onMapReady(GoogleMap map) {
    map.addMarker(new MarkerOptions()
        .position(new LatLng(10, 10))
        .title("Hello world"));
}

Exibir informações adicionais sobre um marcador

Um requisito comum é mostrar mais informações sobre um lugar ou local quando o usuário toca em um marcador no mapa. Consulte o guia sobre janelas de informações.

Associar dados a um marcador

Você pode armazenar um objeto de dados arbitrários com um marcador usando Marker.setTag() e recuperar esse objeto utilizando Marker.getTag(), conforme esta amostra de código:

/**
 * A demo class that stores and retrieves data objects with each marker.
 */
public class MarkerDemoActivity extends FragmentActivity implements
        OnMarkerClickListener,
        OnMapReadyCallback {

    private static final LatLng PERTH = new LatLng(-31.952854, 115.857342);
    private static final LatLng SYDNEY = new LatLng(-33.87365, 151.20689);
    private static final LatLng BRISBANE = new LatLng(-27.47093, 153.0235);

    private Marker mPerth;
    private Marker mSydney;
    private Marker mBrisbane;

    private GoogleMap mMap;

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

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

    /** Called when the map is ready. */
    @Override
    public void onMapReady(GoogleMap map) {
        mMap = map;

        // Add some markers to the map, and add a data object to each marker.
        mPerth = mMap.addMarker(new MarkerOptions()
                .position(PERTH)
                .title("Perth"));
        mPerth.setTag(0);

        mSydney = mMap.addMarker(new MarkerOptions()
                .position(SYDNEY)
                .title("Sydney"));
        mSydney.setTag(0);

        mBrisbane = mMap.addMarker(new MarkerOptions()
                .position(BRISBANE)
                .title("Brisbane"));
        mBrisbane.setTag(0);

        // Set a listener for marker click.
        mMap.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;
    }
}

Veja 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 você quer que eles se comportem de forma diferente após um clique. Para fazer isso, armazene uma String com o marcador indicando o tipo.
  • Você está interagindo 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 no marcador e mantenha-o pressionado para arrastá-lo. 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 adicioná-lo 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.

static final LatLng PERTH = new LatLng(-31.90, 115.86);
Marker perth = mMap.addMarker(new MarkerOptions()
                          .position(PERTH)
                          .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 objeto Marker.
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 é exibida 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 é exibido 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 como false.
Visible
Defina como false para tornar o marcador invisível. Por padrão, é configurado como true.
Orientação "Flat" ou "Billboard"
Por padrão, os marcadores são orientados em relação à tela e não giram nem se inclinam com a câmera. Marcadores planos são orientados em relação à superfície da Terra e giram e se inclinam com a câmera. Os dois tipos de marcador não mudam de tamanho com base no zoom. Use GroundOverlays se você quiser esse efeito.
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 único marcador com o ícone padrão.

static final LatLng MELBOURNE = new LatLng(-37.813, 144.962);
Marker melbourne = mMap.addMarker(new MarkerOptions()
                          .position(MELBOURNE));

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.

static final LatLng MELBOURNE = new LatLng(-37.813, 144.962);
Marker melbourne = mMap.addMarker(new MarkerOptions()
                          .position(MELBOURNE)
                          .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" deve ser especificado como um valor flutuante entre 0 e 1, em que 0 é totalmente transparente, e 1 é totalmente opaco.

static final LatLng MELBOURNE = new LatLng(-37.813, 144.962);
Marker melbourne = mMap.addMarker(new MarkerOptions()
                          .position(MELBOURNE)
                          .alpha(0.7f));

Personalizar a imagem do marcador

Você pode substituir a imagem do marcador padrão por uma personalizada, muitas vezes chamada de ícone. Ícones personalizados são sempre definidos como um BitmapDescriptor e 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 código do recurso de uma imagem em bitmap.

O snippet abaixo cria um marcador com um ícone personalizado.

  private static final LatLng MELBOURNE = new LatLng(-37.813, 144.962);
  private Marker melbourne = mMap.addMarker(new MarkerOptions()
                            .position(MELBOURNE)
                            .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 irão girar quando o mapa também for girado e mudarão 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.

static final LatLng PERTH = new LatLng(-31.90, 115.86);
Marker perth = mMap.addMarker(new MarkerOptions()
                          .position(PERTH)
                          .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.

static final LatLng PERTH = new LatLng(-31.90, 115.86);
Marker perth = mMap.addMarker(new MarkerOptions()
                          .position(PERTH)
                          .anchor(0.5,0.5)
                          .rotation(90.0));

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:

@Override
public void onMapReady(GoogleMap map) {
    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 do 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().