Indicatori

Seleziona piattaforma: Android iOS JavaScript

Gli indicatori indicano le singole posizioni sulla mappa. Puoi personalizzare gli indicatori cambiando il colore predefinito o sostituendo l'icona dell'indicatore con un'immagine personalizzata. Le finestre informative possono fornire maggiore contesto a un indicatore.

Esempi di codice

Il repository APIDemos su GitHub include un esempio che illustra varie funzionalità degli indicatori:

Java

Kotlin

Introduzione

Gli indicatori identificano le posizioni sulla mappa. L'indicatore predefinito utilizza un'icona standard, simile all'aspetto di Google Maps. È possibile modificare il colore, l'immagine o il punto di ancoraggio dell'icona tramite l'API. Gli indicatori sono oggetti di tipo Marker e vengono aggiunti alla mappa con il metodo GoogleMap.addMarker(markerOptions).

Gli indicatori sono progettati per essere interattivi. Ricevono gli eventi click per impostazione predefinita e vengono spesso utilizzati con i listener di eventi per aprire le finestre informative. L'impostazione della proprietà draggable di un indicatore su true consente all'utente di modificare la posizione dell'indicatore. Premi a lungo per attivare la possibilità di spostare l'indicatore.

Per impostazione predefinita, quando un utente tocca un indicatore, la barra degli strumenti della mappa viene visualizzata nella parte in basso a destra della mappa, consentendo all'utente di accedere rapidamente all'app per dispositivi mobili Google Maps. Puoi disattivare la barra degli strumenti. Per ulteriori informazioni, consulta la guida ai controlli.

Guida introduttiva agli indicatori

In questa puntata di Maps Live vengono spiegate le nozioni di base per aggiungere indicatori alla mappa utilizzando l'SDK Maps per Android.

Aggiungi un marcatore

L'esempio seguente mostra come aggiungere un indicatore a una mappa. L'indicatore viene creato alle coordinate -33.852,151.211 (Sydney, Australia) e, quando viene fatto clic, viene visualizzata la stringa "Marker a 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));
}

      

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))
}

      

Visualizza ulteriori informazioni su un indicatore

Un requisito comune è mostrare informazioni aggiuntive su un luogo o una località quando l'utente tocca un indicatore sulla mappa. Consulta la guida alle finestre informative.

Associare dati a un indicatore

Puoi archiviare un oggetto dati arbitrario con un indicatore tramite Marker.setTag() e recuperare l'oggetto dati utilizzando Marker.getTag(). L'esempio riportato di seguito mostra come puoi conteggiare il numero di volte in cui è stato fatto clic su un indicatore utilizzando i tag:

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;
    }
}

      

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
    }
}

      

Di seguito sono riportati alcuni esempi di scenari utili per archiviare e recuperare i dati con gli indicatori:

  • L'app può soddisfare diversi tipi di indicatori e vuoi trattarli in modo diverso quando l'utente fa clic su di essi. Per farlo, puoi memorizzare un elemento String con un indicatore che ne indica il tipo.
  • Potresti interfacciarti con un sistema con identificatori di record univoci, in cui gli indicatori rappresentano record specifici in quel sistema.
  • I dati dell'indicatore possono indicare una priorità da utilizzare nel decidere lo z-index di un indicatore.

Rendi trascinabile un indicatore

Puoi riposizionare un indicatore dopo averlo aggiunto alla mappa purché la sua proprietà draggable sia impostata su true. Premi a lungo l'indicatore per attivare il trascinamento. Togliendo il dito dallo schermo, l'indicatore rimarrà in quella posizione.

Non è possibile trascinare gli indicatori per impostazione predefinita. Devi impostare esplicitamente l'indicatore per essere tracciabile con MarkerOptions.draggable(boolean) prima di aggiungerlo alla mappa o Marker.setDraggable(boolean) dopo averlo aggiunto alla mappa. Puoi ascoltare gli eventi di trascinamento sull'indicatore, come descritto nella sezione Eventi di trascinamento degli indicatori.

Lo snippet riportato di seguito aggiunge un indicatore trascinabile a Perth, Australia.

Java


final LatLng perthLocation = new LatLng(-31.90, 115.86);
Marker perth = map.addMarker(
    new MarkerOptions()
        .position(perthLocation)
        .draggable(true));

      

Kotlin


val perthLocation = LatLng(-31.90, 115.86)
val perth = map.addMarker(
    MarkerOptions()
        .position(perthLocation)
        .draggable(true)
)

      

Personalizzare un indicatore

Questo video mostra i modi per utilizzare gli indicatori per visualizzare le posizioni su una mappa.

Gli indicatori possono definire un'immagine personalizzata da visualizzare al posto dell'icona predefinita. La definizione di un'icona comporta l'impostazione di una serie di proprietà che influiscono sul comportamento visivo dell'indicatore.

Gli indicatori supportano la personalizzazione tramite le seguenti proprietà:

Posizione (obbligatoria)
Il valore LatLng per la posizione dell'indicatore sulla mappa. Questa è l'unica proprietà obbligatoria per un oggetto Marker.
Ancora
Il punto nell'immagine che verrà posizionato nella posizione LatLng dell'indicatore. L'impostazione predefinita è il centro della parte inferiore dell'immagine.
Alpha
Imposta l'opacità dell'indicatore. Il valore predefinito è 1,0.
Titolo
Una stringa che viene visualizzata nella finestra informativa quando l'utente tocca l'indicatore.
Snippet
Testo aggiuntivo che viene visualizzato sotto il titolo.
Icona
Una bitmap che viene visualizzata al posto dell'immagine predefinita dell'indicatore.
Trascinabile
Imposta su true se vuoi consentire all'utente di spostare l'indicatore. Il valore predefinito è false.
Visibile
Imposta su false per rendere invisibile l'indicatore. Il valore predefinito è true.
Orientamento piatto o cartellone
Per impostazione predefinita, gli indicatori utilizzano un orientamento per un cartellone pubblicitario, ovvero sono disegnati rispetto allo schermo del dispositivo anziché alla superficie della mappa. La rotazione, l'inclinazione o lo zoom della mappa non modificano l'orientamento dell'indicatore. Puoi impostare l'orientamento di un indicatore in modo che sia piano rispetto alla terra. Gli indicatori fissi ruotano quando la mappa viene ruotata e cambia la prospettiva quando la mappa è inclinata. Come per gli indicatori sui cartelloni, gli indicatori fissi mantengono le proprie dimensioni quando la mappa viene ingrandita o rimpicciolita.
Rotazione
L'orientamento dell'indicatore, espresso in gradi in senso orario. La posizione predefinita cambia se l'indicatore è piatto. La posizione predefinita per un indicatore piatto è allineata a nord. Quando l'indicatore non è piatto, la posizione predefinita è rivolta verso l'alto e la rotazione è tale che l'indicatore sia sempre rivolto verso la fotocamera.

Lo snippet di seguito crea un indicatore semplice, con l'icona predefinita.

Java


final LatLng melbourneLocation = new LatLng(-37.813, 144.962);
Marker melbourne = map.addMarker(
    new MarkerOptions()
        .position(melbourneLocation));

      

Kotlin


val melbourneLocation = LatLng(-37.813, 144.962)
val melbourne = map.addMarker(
    MarkerOptions()
        .position(melbourneLocation)
)

      

Personalizza il colore dell'indicatore

È possibile personalizzare il colore dell'immagine predefinita dell'indicatore passando un oggetto BitmapDescriptor al metodo icon(). Puoi utilizzare un insieme di colori predefiniti nell'oggetto BitmapDescriptorFactory oppure impostare un colore di indicatore personalizzato con il metodo BitmapDescriptorFactory.defaultMarker(float hue). La tonalità è un valore compreso tra 0 e 360, che rappresenta i punti su una ruota dei colori.

Java


final LatLng melbourneLocation = new LatLng(-37.813, 144.962);
Marker melbourne = map.addMarker(
    new MarkerOptions()
        .position(melbourneLocation)
        .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE)));

      

Kotlin


val melbourneLocation = LatLng(-37.813, 144.962)
val melbourne = map.addMarker(
    MarkerOptions()
        .position(melbourneLocation)
        .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE))
)

      

Personalizza l'opacità dell'indicatore

Puoi controllare l'opacità di un indicatore con il metodo penOptions.alpha(). Il valore alfa deve essere specificato come numero in virgola mobile compreso tra 0,0 e 1,0, dove 0 è completamente trasparente e 1 è completamente opaco.

Java


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

      

Kotlin


val melbourneLocation = LatLng(-37.813, 144.962)
val melbourne = map.addMarker(
    MarkerOptions()
        .position(melbourneLocation)
        .alpha(0.7f)
)

      

Personalizzare l'immagine dell'indicatore

Puoi sostituire l'immagine dell'indicatore predefinita con un'immagine personalizzata, spesso chiamata icona. Le icone personalizzate vengono sempre impostate come BitmapDescriptor e definite con uno dei metodi disponibili nella classe BitmapDescriptorFactory.

fromAsset(String assetName)
Crea un indicatore personalizzato usando il nome di un'immagine Bitmap nella directory degli asset.
fromBitmap(Bitmap image)
Crea un indicatore personalizzato da un'immagine Bitmap.
fromFile(String fileName)
Crea un'icona personalizzata usando il nome di un file immagine Bitmap che si trova nella memoria interna.
fromPath(String absolutePath)
Crea un indicatore personalizzato dal percorso di un file assoluto di un'immagine Bitmap.
fromResource(int resourceId)
Crea un indicatore personalizzato mediante l'ID risorsa di un'immagine Bitmap.

Lo snippet di seguito crea un indicatore con un'icona personalizzata.

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)));

      

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))
)

      

Appiattire un indicatore

In genere le icone degli indicatori vengono disegnate rispetto allo schermo; la rotazione, l'inclinazione o lo zoom della mappa non modificano l'orientamento dell'indicatore. Puoi impostare l'orientamento di un indicatore in modo che sia piatto rispetto alla terra. Gli indicatori che vengono orientati in questo modo ruotano quando la mappa viene ruotata e cambia la prospettiva quando la mappa è inclinata. Gli indicatori fissi manterranno le loro dimensioni quando la mappa viene ingrandita o rimpicciolita.

Per modificare l'orientamento dell'indicatore, imposta la relativa proprietà flat su true.

Java


final LatLng perthLocation = new LatLng(-31.90, 115.86);
Marker perth = map.addMarker(
    new MarkerOptions()
        .position(perthLocation)
        .flat(true));

      

Kotlin


val perthLocation = LatLng(-31.90, 115.86)
val perth = map.addMarker(
    MarkerOptions()
        .position(perthLocation)
        .flat(true)
)

      

Ruotare un indicatore

Puoi ruotare un indicatore intorno al suo punto di ancoraggio con Marker.Metodo setRotation(). La rotazione viene misurata in gradi in senso orario dalla posizione predefinita. Quando l'indicatore è piatto sulla mappa, la posizione predefinita è Nord. Quando l'indicatore non è piatto, la posizione predefinita è rivolta verso l'alto e la rotazione è tale che l'indicatore sia sempre rivolto verso la fotocamera.

L'esempio riportato di seguito ruota l'indicatore di 90°. Se viene impostato il punto di ancoraggio su 0.5,0.5, l'indicatore viene ruotato attorno al centro anziché sulla base.

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));

      

Kotlin


val perthLocation = LatLng(-31.90, 115.86)
val perth = map.addMarker(
    MarkerOptions()
        .position(perthLocation)
        .anchor(0.5f, 0.5f)
        .rotation(90.0f)
)

      

Indice z-index

Lo z-index specifica l'ordine di stack di questo indicatore, rispetto agli altri indicatori sulla mappa. Un indicatore con uno z-index alto viene disegnato sopra quelli con uno z-index più basso. Il valore predefinito di z-index è 0.

Imposta lo z-index sull'oggetto opzioni dell'indicatore chiamando MarkerOptions.zIndex(), come mostrato nel seguente snippet di codice:

Java


map.addMarker(new MarkerOptions()
    .position(new LatLng(10, 10))
    .title("Marker z1")
    .zIndex(1.0f));

      

Kotlin


map.addMarker(
    MarkerOptions()
        .position(LatLng(10.0, 10.0))
        .title("Marker z1")
        .zIndex(1.0f)
)

      

Puoi accedere allo z-index dell'indicatore chiamando Marker.getZIndex() e puoi modificarlo chiamando Marker.setZIndex().

Gli indicatori vengono sempre tracciati sopra i livelli di riquadri e altri overlay non indicatori (overlay del terreno, polilinee, poligoni e altre forme) indipendentemente dallo z-index degli altri overlay. In realtà, gli indicatori sono considerati in un gruppo z-index separato rispetto agli altri overlay.

Leggi ulteriori informazioni sull'effetto di z-index sugli eventi di clic di seguito.

Gestire gli eventi dell'indicatore

L'API di Google Maps ti consente di ascoltare gli eventi e rispondere agli indicatori. Per ascoltare questi eventi, devi impostare il listener corrispondente sull'oggetto GoogleMap a cui appartengono gli indicatori. Quando l'evento si verifica su uno degli indicatori sulla mappa, il callback dell'ascoltatore viene richiamato con l'oggetto Marker corrispondente trasmesso come parametro. Per confrontare questo oggetto Marker con il tuo riferimento con un oggetto Marker, devi utilizzare equals() e non ==.

Puoi ascoltare i seguenti eventi:

Eventi relativi ai clic sull'indicatore

Puoi utilizzare una OnMarkerClickListener per ascoltare gli eventi di clic sull'indicatore. Per impostare questo listener sulla mappa, chiama GoogleMap.setOnMarkerClickListener(OnMarkerClickListener). Quando un utente fa clic su un indicatore, viene richiamato onMarkerClick(Marker), che viene passato come argomento. Questo metodo restituisce un valore booleano che indica se hai utilizzato l'evento (ovvero, vuoi eliminare il comportamento predefinito). Se restituisce false, il comportamento predefinito si aggiunge al comportamento personalizzato. Il comportamento predefinito per un evento di clic su un indicatore prevede la visualizzazione della sua finestra informativa (se disponibile) e di spostare la fotocamera in modo che l'indicatore sia centrato sulla mappa.

Effetto di z-index sugli eventi di clic:

  • Quando un utente fa clic su un cluster di indicatori, l'evento di clic viene attivato per l'indicatore con lo z-index più elevato.
  • Viene attivato al massimo un evento per clic. In altre parole, il clic non viene trasmesso agli indicatori o ad altri overlay con valori z-index inferiori.
  • Il clic su un cluster di indicatori fa sì che i clic successivi ruotino nel cluster, selezionandoli a turni. L'ordine del ciclo assegna prima la priorità a z-index e poi la vicinanza al punto di clic.
  • Se l'utente fa clic al di fuori della vicinanza del cluster, l'API ricalcola il cluster e reimposta lo stato del ciclo dei clic in modo che inizi dall'inizio.
  • L'evento di clic passa attraverso i cluster di indicatori ad altre forme e overlay prima di riavviare il ciclo.
  • Gli indicatori sono effettivamente considerati in un gruppo z-index separato rispetto ad altri overlay o forme (polilinee, poligoni, cerchi e/o overlay al suolo), indipendentemente dallo z-index degli altri overlay. Se più indicatori, overlay o forme sono sovrapposti, l'evento di clic viene prima visualizzato in loop tramite il cluster di indicatori, quindi viene attivato per altri overlay o forme cliccabili, in base ai loro valori z-index.

Eventi di trascinamento degli indicatori

Puoi utilizzare una OnMarkerDragListener per ascoltare gli eventi di trascinamento su un indicatore. Per impostare questo listener sulla mappa, chiama GoogleMap.setOnMarkerDragListener. Per trascinare un indicatore, l'utente deve premere a lungo sull'indicatore. Quando l'utente toglie il dito dallo schermo, l'indicatore rimarrà in quella posizione. Quando un indicatore viene trascinato, onMarkerDragStart(Marker) viene richiamato inizialmente. Mentre l'indicatore viene trascinato, onMarkerDrag(Marker) viene richiamato costantemente. Alla fine del trascinamento onMarkerDragEnd(Marker) viene richiamato. Puoi ottenere la posizione dell'indicatore in qualsiasi momento chiamando il numero Marker.getPosition().