Los marcadores indican ubicaciones únicas en el mapa. Si deseas personalizar los marcadores, puedes cambiar el color predeterminado o reemplazar su ícono por una imagen personalizada. Las ventanas de información pueden proporcionarle contexto adicional a un marcador.
Muestras de código
El repositorio ApiDemos en GitHub incluye un ejemplo que muestra varias funciones de los marcadores:
Kotlin
- MapWithMarker: Un mapa simple con un marcador (consulta el instructivo sobre cómo agregar un mapa con un marcador)
- MarkerDemoActivity: Uso de marcadores en un mapa, incluidos objetos de escucha y opciones
Java
- MapWithMarker: Un mapa simple con un marcador (consulta el instructivo sobre cómo agregar un mapa con un marcador)
- MarkerDemoActivity: Uso de marcadores en un mapa, incluidos objetos de escucha y opciones
Introducción
Los marcadores identifican ubicaciones en el mapa. El marcador predeterminado utiliza un ícono estándar, que refleja el estilo de Google Maps. Es posible cambiar el color, la imagen o el punto de anclaje del ícono a través de la API. Los marcadores son objetos de tipo Marker
y se agregan al mapa con el método GoogleMap.addMarker(markerOptions)
.
Los marcadores están diseñados para ser interactivos. Reciben eventos de clic (click
) de forma predeterminada y, a menudo, se utilizan con los objetos de escucha de eventos para mostrar ventanas de información. Si la propiedad draggable
de un marcador se configura en true
, el usuario podrá cambiar su posición. Para ello, deberás mantenerlo presionado y arrastrarlo.
De forma predeterminada, cuando un usuario presiona un marcador, aparece la barra de herramientas del mapa en la esquina inferior derecha. Esta barra de herramientas le proporciona al usuario un acceso rápido a la app para dispositivos móviles de Google Maps. Puedes inhabilitarla si lo deseas. Para obtener más información, consulta la guía de controles.
Cómo comenzar a utilizar marcadores
En este episodio de Maps Live, se comparte información básica sobre cómo agregar marcadores a tu mapa con SDK de Maps para Android.
Agrega un marcador
En el siguiente ejemplo, se muestra cómo agregar un marcador a un mapa. El marcador se crea en las coordenadas -33.852,151.211
(Sídney, Australia) y muestra la cadena "Marcador en Sídney" en una ventana de información cuando se hace clic en él.
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)); }
Muestra información adicional sobre un marcador
Un requisito común es el de mostrar información adicional sobre un lugar o una ubicación cuando el usuario presiona un marcador en el mapa. Consulta la guía sobre ventanas de información.
Asocia datos a un marcador
Utiliza el método Marker.setTag()
para almacenar un objeto de datos arbitrario con un marcador y el método Marker.getTag()
para recuperar dicho objeto. En el ejemplo que se incluye a continuación, se muestra cómo puedes contar la cantidad de veces que se hizo clic en un marcador mediante el uso de etiquetas:
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; } }
A continuación, se incluyen algunos ejemplos de situaciones en las que resulta útil almacenar y recuperar datos con marcadores:
- Tu app proporciona distintos tipos de marcadores, y debes tratarlos de manera diferente cuando el usuario hace clic en ellos. Para ello, puedes almacenar una cadena (
String
) con el marcador y también indicar el tipo. - Es posible que interactúes con un sistema que tiene identificadores de registro únicos, y los marcadores representan registros específicos en ese sistema.
- Los datos del marcador indican que se use una prioridad para determinar el índice z del marcador.
Configura un marcador para que sea arrastrable
Puedes cambiar la posición de un marcador tras agregarlo al mapa, siempre que su propiedad draggable
esté configurada en true
. Mantén presionado el marcador para habilitar la función de arrastre. Cuando quites el dedo de la pantalla, el marcador permanecerá en esa posición.
De forma predeterminada, los marcadores no son arrastrables. Debes configurarlos explícitamente como tales con el método MarkerOptions.draggable(boolean)
antes de agregarlos al mapa o con el método Marker.setDraggable(boolean)
después de agregarlos.
Consulta Eventos de arrastre del marcador para obtener información sobre cómo escuchar estos eventos.
El siguiente fragmento agrega un marcador arrastrable en Perth, Australia.
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));
Personaliza un marcador
En este video, se muestran diferentes maneras de utilizar marcadores para visualizar ubicaciones en un mapa.
Los marcadores se pueden configurar para mostrar una imagen personalizada en lugar del ícono predeterminado. Para ello, se debe establecer una serie de propiedades que afectan el comportamiento visual del marcador.
Los marcadores admiten la personalización a través de las siguientes propiedades:
- Posición (propiedad obligatoria)
- Es el valor
LatLng
correspondiente a la posición del marcador en el mapa. Es la única propiedad obligatoria de un objetoMarker
. - Anclaje
- Es el punto en la imagen que se colocará en la posición LatLng del marcador. La ubicación predeterminada es en el medio de la parte inferior de la imagen.
- Alfa
- Establece la opacidad del marcador. El valor predeterminado es 1.0.
- Título
- Es una cadena que se muestra en la ventana de información cuando el usuario presiona el marcador.
- Fragmento
- Es el texto adicional que se muestra debajo del título.
- Ícono
- Es un mapa de bits que se muestra en lugar de la imagen predeterminada del marcador.
- Arrastrable
- Establece esta propiedad en
true
si deseas permitir que el usuario mueva el marcador. La configuración predeterminada esfalse
. - Visible
- Establece esta propiedad en
false
para que el marcador sea invisible. La configuración predeterminada estrue
. - Orientación plana y tipo billboard
- De forma predeterminada, los marcadores usan una orientación de billboard, lo que significa que se dibujan orientados respecto de la pantalla del dispositivo y no de la superficie del mapa. La rotación, la inclinación o el zoom del mapa no cambian la orientación del marcador. Puedes configurar la orientación de un marcador de modo que se vea plano respecto de la Tierra. Los marcadores planos rotan cuando se gira el mapa y cambian de perspectiva cuando este se inclina. Al igual que los marcadores con orientación de billboard, los marcadores planos conservan su tamaño cuando el mapa se acerca o aleja.
- Rotación
- Es la orientación del marcador, especificada en grados en el sentido de las manecillas del reloj. La posición predeterminada cambia si el marcador es plano. La posición predeterminada de un marcador plano se alinea respecto del norte. Si se utiliza un marcador de otro tipo, la posición predeterminada es hacia arriba y la rotación hace que siempre apunte hacia la cámara.
El siguiente fragmento crea un marcador simple con el ícono predeterminado.
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));
Personaliza el color del marcador
Para personalizar el color de la imagen predeterminada del marcador, pasa un objeto BitmapDescriptor
al método icon(). Puedes utilizar un conjunto de colores predefinidos en el objeto BitmapDescriptorFactory
o establecer un color de marcador personalizado con el método BitmapDescriptorFactory.defaultMarker(float hue)
. El matiz debe ser un valor entre 0 y 360, lo que representa un punto determinado en una paleta de colores.
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)));
Personaliza la opacidad del marcador
Puedes controlar la opacidad de un marcador con el método MarkerOptions.alpha(). Se debe especificar el valor alfa con un número de punto flotante entre 0.0 y 1.0, donde 0 es completamente transparente y 1 es completamente 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));
Personaliza la imagen del marcador
Puedes reemplazar la imagen predeterminada del marcador por una personalizada, que suele llamarse ícono. Los íconos personalizados siempre se configuran como un objeto BitmapDescriptor
y se definen con uno de los métodos de la clase BitmapDescriptorFactory
.
fromAsset(String assetName)
- Crea un marcador personalizado con el nombre de una imagen de mapa de bits en el directorio de recursos.
fromBitmap(Bitmap image)
- Crea un marcador personalizado a partir de una imagen de mapa de bits.
fromFile(String fileName)
- Crea un ícono personalizado con el nombre de un archivo de imagen de mapa de bits ubicado en el almacenamiento interno.
fromPath(String absolutePath)
- Crea un marcador personalizado a partir de una ruta de acceso absoluta a un archivo de imagen de mapa de bits.
fromResource(int resourceId)
- Crea un marcador personalizado con el ID de recurso de una imagen de mapa de bits.
El siguiente fragmento crea un marcador con un ícono 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)));
Configura un marcador plano
Los íconos de marcador suelen dibujarse orientados respecto de la pantalla. Esto significa que no se cambiará su orientación al rotar, inclinar, acercar o alejar el mapa. Puedes configurar marcadores planos para que su orientación cambie con la de la Tierra. De esta manera, los marcadores rotarán cuando se rote el mapa y cambiarán de perspectiva cuando se lo incline. Los marcadores planos conservarán su tamaño cuando se acerque o se aleje el mapa.
Para cambiar la orientación del marcador, configura la propiedad flat
del marcador en 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));
Rota un marcador
Puedes rotar un marcador alrededor de su punto de anclaje con el método Marker
.setRotation()
. La rotación se mide en grados en el sentido de las manecillas del reloj respecto de la posición predeterminada. Si se utiliza un marcador plano en el mapa, la posición predeterminada es el norte. Si se utiliza un marcador de otro tipo, la posición predeterminada es hacia arriba y la rotación hace que siempre apunte hacia la cámara.
En el siguiente ejemplo, el marcador rota 90°. Al configurar el punto de anclaje en 0.5,0.5
, el marcador rota sobre su centro, en lugar de hacerlo sobre su 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));
Índice z del marcador
El índice z especifica el orden en que se debe apilar este marcador respecto de otros en el mapa. Un marcador con un índice z alto se dibujará encima de aquellos con índices z más bajos. El valor predeterminado del índice z es 0
.
Para establecer el índice z en el objeto de opciones del marcador, llama a MarkerOptions.zIndex()
, como se muestra en el siguiente fragmento de código:
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));
Para acceder al índice z del marcador, llama a Marker.getZIndex()
y, para cambiarlo, llama a Marker.setZIndex()
.
Los marcadores siempre se dibujan encima de las capas de mosaicos y otras superposiciones que no corresponden a marcadores (superposiciones de suelo, polilíneas, polígonos y otras formas), sin importar el índice z de las demás superposiciones. Se considera que los marcadores pertenecen efectivamente a un grupo de índice z separado de otras superposiciones.
Obtén información acerca del efecto del índice z sobre los eventos de clic más abajo.
Controla los eventos de marcador
La API de Google Maps te permite escuchar y responder eventos de marcador. Para escuchar estos eventos, debes configurar el objeto de escucha correspondiente en el objeto GoogleMap
al que pertenecen los marcadores. Cuando se produzca el evento en uno de los marcadores del mapa, se invocará la devolución de llamada del objeto de escucha y se pasará el objeto Marker
correspondiente como parámetro. Para comparar este objeto Marker
con tu propia referencia a un objeto Marker
, debes utilizar equals()
y no ==
.
Puedes escuchar los siguientes eventos:
- Eventos de clic en el marcador
- Eventos de arrastre del marcador
- Eventos de clic en la ventana de información
Eventos de clic en el marcador
Puedes utilizar un objeto OnMarkerClickListener
para escuchar los eventos de clic en el marcador. Para configurar este objeto de escucha en el mapa, llama a GoogleMap.setOnMarkerClickListener(OnMarkerClickListener)
. Cuando un usuario haga clic en un marcador, se llamará a onMarkerClick(Marker)
y se pasará el marcador como argumento. Este método muestra un valor booleano que indica si consumiste el evento (es decir, si deseas suprimir el comportamiento predeterminado). Si muestra false
, se sumará el comportamiento predeterminado al comportamiento personalizado. El comportamiento predeterminado de un evento de clic en el marcador es mostrar la ventana de información relevante (si corresponde) y mover la cámara para que el marcador quede centrado en el mapa.
Efecto del índice z en los eventos de clic:
- Cuando un usuario hace clic en un clúster de marcadores, se activa el evento de clic para el marcador con el índice z más alto.
- Como máximo, se activará un evento por clic. En otras palabras, el clic no se pasa a los marcadores ni a otras superposiciones con valores del índice z más bajos.
- Al hacer clic en un clúster de marcadores, se generan distintos clics para cada elemento del clúster de forma cíclica para seleccionar cada uno de ellos. Para determinar el orden del ciclo, primero se prioriza el índice z y, luego, la proximidad al punto del clic.
- Si el usuario hace clic fuera de la proximidad del clúster, la API vuelve a calcular el clúster y restablece el estado del ciclo de clics para que comience desde el principio.
- Antes de que se reinicie el ciclo, el evento de clic pasa de los clústeres de marcadores a otras formas y superposiciones.
- Se considera que los marcadores pertenecen efectivamente a un grupo de índice z separado de otras superposiciones o formas (polilíneas, polígonos, círculos o superposiciones de suelo), sin considerar el índice z de las demás superposiciones. Si varios marcadores, superposiciones o formas se apilan unos sobre otros, el evento de clic primero pasará por el clúster de marcadores y, luego, se activará para otras superposiciones o formas en las que se pueda hacer clic según sus valores del índice z.
Eventos de arrastre del marcador
Puedes utilizar un objeto OnMarkerDragListener
para escuchar los eventos de arrastre de un marcador. Para configurar este objeto de escucha en el mapa, llama a GoogleMap.setOnMarkerDragListener
. Para arrastrar un marcador, el usuario debe mantenerlo presionado. Cuando quite el dedo de la pantalla, el marcador permanecerá en esa posición. Cuando se comienza a arrastrar un marcador, primero se llama a onMarkerDragStart(Marker)
. Mientras se lo arrastra, se llama a onMarkerDrag(Marker)
de forma constante. Y cuando se termina de arrastrar, se llama a onMarkerDragEnd(Marker)
. Para obtener la posición del marcador en cualquier momento, llama a Marker.getPosition()
.