Znaczniki wskazują pojedyncze lokalizacje na mapie. Znaczniki możesz dostosowywać, zmieniając kolor domyślny lub zastępując ich ikonę obrazem niestandardowym. Okna informacyjne mogą stanowić dodatkowy kontekst znacznika.
Przykładowe fragmenty kodu
Repozytorium ApiDemos w GitHubie zawiera próbkę pokazującą różne funkcje znaczników:
Java
- MapWithMarker: prosta mapa ze znacznikiem. Zobacz samouczek na temat dodawania mapy ze znacznikami.
- MarkerDemoActivity: używanie znaczników na mapie, w tym opcji i słuchaczy.
Kotlin
- MapWithMarker: prosta mapa ze znacznikiem. Zobacz samouczek na temat dodawania mapy za pomocą znacznika.
- MarkerDemoActivity: używanie znaczników na mapie, w tym opcji i słuchaczy.
Wprowadzenie
Znaczniki identyfikują lokalizacje na mapie. Znacznik domyślny używa standardowej ikony, która jest typowa dla wyglądu i sposobu działania Map Google. W interfejsie API można zmienić kolor, obraz lub punkt zakotwiczenia ikony. Znaczniki to obiekty typu Marker
. Są one dodawane do mapy metodą GoogleMap.addMarker(markerOptions)
.
Znaczniki są interaktywne. Domyślnie otrzymują zdarzenia click
i są często używane do nasłuchiwania okna informacyjnego. Ustawienie właściwości znacznika draggable
na true
umożliwia użytkownikowi zmianę pozycji znacznika. Przytrzymaj znacznik,
aby aktywować możliwość przenoszenia znacznika.
Domyślnie po kliknięciu znacznika użytkownik widzi pasek narzędzi mapy w prawym dolnym rogu mapy i daje szybki dostęp do aplikacji mobilnej Mapy Google. Możesz wyłączyć pasek narzędzi. Więcej informacji znajdziesz w przewodniku po elementach sterujących.
Pierwsze kroki ze znacznikami
Ten odcinek Map Live na żywo zawiera podstawowe informacje o dodawaniu znaczników do mapy za pomocą pakietu Maps SDK na Androida.
Dodaj znacznik
Poniższy przykład pokazuje, jak dodać znacznik do mapy. Znacznik jest tworzony we współrzędnej -33.852,151.211
(Sydney, Australia). Po kliknięciu powoduje wyświetlenie ciągu znaków „Marker in Sydney” w oknie informacyjnym.
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)) }
Wyświetl dodatkowe informacje o znacznikach
Częstym wymaganiem jest wyświetlanie dodatkowych informacji o miejscu lub lokalizacji, gdy użytkownik kliknie znacznik na mapie. Przeczytaj przewodnik dotyczący okna informacyjnego.
Powiązanie danych ze znacznikiem
Obiekt danych możesz zapisać za pomocą znacznika przy użyciu znacznika Marker.setTag()
, a obiekt pobrać za pomocą Marker.getTag()
. Przykład poniżej pokazuje, jak można liczyć kliknięcia tagu za pomocą tagów:
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 } }
Oto kilka przykładowych scenariuszy, w których można przechowywać i pobierać dane za pomocą znaczników:
- Aplikacja obsługuje różne rodzaje znaczników i chcesz je traktować różnie, gdy użytkownicy je klikają. W tym celu możesz zapisać
String
przy użyciu znacznika wskazującego typ. - Być może korzystasz z systemu, który ma unikalne identyfikatory rekordów, w których znaczniki reprezentują określone rekordy w tym systemie.
- Dane znacznika mogą wskazywać priorytet, który należy stosować przy podejmowaniu kolejności nakładania elementów.
Włącz przesuwanie znacznika
Po dodaniu znacznika do mapy możesz zmienić jego pozycję, o ile właściwość draggable
jest ustawiona na true
. Przytrzymaj znacznik,
aby włączyć przeciąganie. Gdy zdejmiesz palec z ekranu, znacznik pozostanie w tym miejscu.
Znaczników nie można domyślnie przeciągać. Znacznik musi być wyraźnie ustawiany do przeciągania (MarkerOptions.draggable(boolean)
) przed dodaniem go do mapy lub Marker.setDraggable(boolean)
po dodaniu do mapy.
Możesz nasłuchiwać zdarzeń przeciągania w znaczniku, tak jak to opisano w sekcji Zdarzenia przeciągania znacznika.
Fragment kodu poniżej dodaje znacznik w Perth w Australii.
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) )
Dostosowywanie znacznika
Ten film pokazuje, jak używać znaczników do wizualizacji lokalizacji na mapie.
Znaczniki mogą określać obraz niestandardowy zamiast ikony domyślnej. Definiowanie ikony obejmuje także określenie właściwości, które mają wpływ na wygląd znacznika.
Znaczniki obsługują dostosowywanie za pomocą następujących właściwości:
- Pozycja (wymagana)
- Wartość
LatLng
pozycji znacznika na mapie. Jest to jedyna wymagana właściwość dla obiektuMarker
. - Kotwica
- Punkt na obrazie, który zostanie umieszczony w pozycji LatLng znacznika. Ta wartość jest domyślnie ustawiana na środku u dołu obrazu.
- Alfa
- Ustawia przezroczystość znacznika. Domyślna wartość to 1.0.
- tytuł,
- Ciąg znaków wyświetlany w oknie informacyjnym, gdy użytkownik kliknie znacznik.
- Krótki opis
- Dodatkowy tekst wyświetlany pod tytułem.
- Ikona
- Mapa bitowa wyświetlana zamiast domyślnego obrazu znacznika.
- Przeciągana
- Ustaw wartość
true
, jeśli chcesz zezwolić użytkownikowi na przesunięcie znacznika. Domyślna wartość tofalse
. - Widoczne
- Ustaw
false
, aby znacznik był niewidoczny. Domyślna wartość totrue
. - Płaska lub orientacja billboardu
- Znaczniki domyślnie używają orientacji billboardu, co oznacza, że są kierowane w kierunku ekranu urządzenia, a nie od powierzchni mapy. Obracanie, pochylanie i powiększanie mapy nie powoduje zmiany orientacji znacznika. Możesz ustawić płaską znacznik względem ziemi. Płaskie znaczniki obracają się po obróceniu mapy i zmieniają perspektywę przy przechyleniu mapy. Podobnie jak w przypadku znaczników billboardów, płaskie znaczniki zachowują swój rozmiar po powiększeniu lub pomniejszeniu mapy.
- Rotacja
- Orientacja znacznika określona w stopniach w prawo. Pozycja domyślna zmienia się, gdy znacznik jest płaski. Domyślnym położeniem płaskiego znacznika jest wyrównanie do północy. Jeśli znacznik nie jest płaski, położenie domyślne jest ustawione w górę, a obrót jest taki, że znacznik jest zawsze skierowany w stronę aparatu.
Fragment kodu poniżej tworzy prosty znacznik z ikoną domyślną.
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) )
Dostosuj kolor znacznika
Można zmienić kolor domyślnego znacznika, przekazując obiekt BitmapDescriptor
do metody icon(). W obiekcie BitmapDescriptorFactory
możesz użyć zestawu wstępnie zdefiniowanych kolorów lub ustawić niestandardowy kolor znacznika za pomocą metody BitmapDescriptorFactory.defaultMarker(float hue)
. Odcień ma wartość od 0 do 360 reprezentującą punkty na kole kolorów.
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)) )
Dostosuj przezroczystość znacznika
Przezroczystość znacznika można kontrolować za pomocą metody MarkupOptions.alpha(). Wartość alfa powinna być liczbą zmiennoprzecinkową z zakresu od 0,0 do 1,0, gdzie 0 oznacza pełną przezroczystość, a 1 – nieprzezroczystość.
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) )
Dostosowywanie obrazu znacznika
Domyślny obraz znacznika możesz zastąpić niestandardowym obrazem, często nazywanym ikoną. Ikony niestandardowe są zawsze ustawiane jako właściwość BitmapDescriptor
i są definiowane za pomocą jednej z metod w klasie BitmapDescriptorFactory
.
fromAsset(String assetName)
- Tworzy znacznik niestandardowy z nazwą obrazu Bitmap w katalogu zasobów.
fromBitmap(Bitmap image)
- Tworzy niestandardowy znacznik na podstawie obrazu mapy bitowej.
fromFile(String fileName)
- Tworzy niestandardową ikonę na podstawie nazwy pliku obrazu Bitmap, który znajduje się w pamięci wewnętrznej.
fromPath(String absolutePath)
- Tworzy znacznik na podstawie bezwzględnej ścieżki pliku obrazu bitmacznego.
fromResource(int resourceId)
- Tworzy niestandardowy znacznik, wykorzystując identyfikator zasobu obrazu Bitmap.
Fragment kodu poniżej pozwala utworzyć znacznik z ikoną niestandardową.
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)) )
Spłaszcz znacznik
Ikony znacznika są zazwyczaj rysowane w odniesieniu do ekranu. Obracanie, pochylanie i powiększanie mapy nie powoduje zmiany orientacji znacznika. Możesz ustawić znacznik, aby płaska płaszczyzna względem Ziemi była aktywna. Znaczniki, które orientują się w ten sposób, będą obracać się, gdy mapa będzie obrócona, i zmieniać perspektywę przy przechyleniu mapy. Stałe znaczniki zachowują swój rozmiar po powiększeniu lub pomniejszeniu mapy.
Aby zmienić orientację znacznika, ustaw właściwość flat
znacznika na 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) )
Obracanie znacznika
Znacznik możesz obracać wokół punktu zakotwiczenia za pomocą polecenia Marker
.Metoda setRotation()
. Obrót jest mierzony w stopniach zgodnie z ruchem wskazówek zegara od pozycji domyślnej. Jeśli znacznik na mapie jest płaski, domyślnie jest ustawiony północ. Jeśli znacznik nie jest płaski, położenie domyślne jest ustawione w górę, a obrót jest taki, że znacznik jest zawsze skierowany w stronę aparatu.
Poniższy przykład obraca znacznik o 90°. Ustawienie punktu zakotwiczenia na 0.5,0.5
powoduje obrót znacznika wokół jego środek, a nie jego podstawy.
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) )
Znacznik kolejności nakładania elementów
Z-index określa kolejność nakładania tego znacznika w odniesieniu do innych znaczników na mapie. Znacznik o dużej kolejności nakładania elementów jest rysowany nad tymi o niższym z-indeksie. Domyślna wartość kolejności nakładania elementów wynosi 0
.
Ustaw wartość kolejności nakładania obiektu obiektu opcji znacznika, wywołując metodę MarkerOptions.zIndex()
, jak pokazano w tym fragmencie kodu:
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) )
Aby uzyskać dostęp do znacznika Z, możesz zadzwonić pod numer Marker.getZIndex()
i zmienić go, dzwoniąc pod numer Marker.setZIndex()
.
Znaczniki są zawsze rysowane nad warstwami płytek i innymi znacznikami (nakładkami na powierzchni, liniami łamanymi, wielokątami i innymi kształtami) niezależnie od kolejności nakładania się pozostałych nakładek. Znaczniki są uważane za oddzielne grupy Z-index w porównaniu z innymi nakładkami.
Dowiedz się więcej o wpływie Z-index na zdarzenia kliknięcia.
Zdarzenia znacznika
Interfejs Maps API umożliwia słuchanie zdarzeń dotyczących znaczników i odpowiadanie na nie. Aby nasłuchiwać tych zdarzeń, musisz ustawić odpowiedni detektor w obiekcie GoogleMap
, do którego należą znaczniki. Gdy zdarzenie występuje na jednym ze znaczników na mapie, wywołanie zwrotne detektora jest wywoływane z odpowiednim obiektem Marker
przekazywanym jako parametr. Aby porównać ten obiekt Marker
z własnym odwołaniem do obiektu Marker
, musisz użyć equals()
, a nie ==
.
Możesz słuchać tych zdarzeń:
- Zdarzenia kliknięcia znacznika
- Wydarzenia dotyczące przeciągania
- Zdarzenia kliknięcia okna informacyjnego
Zdarzenia kliknięcia znacznika
Za pomocą OnMarkerClickListener
możesz nasłuchiwać zdarzeń kliknięcia na znaczniku. Aby ustawić ten detektor na mapie, wywołaj GoogleMap.setOnMarkerClickListener(OnMarkerClickListener)
. Gdy użytkownik kliknie znacznik, wywołana zostanie właściwość onMarkerClick(Marker)
, a znacznik zostanie przekazany jako argument. Ta metoda zwraca wartość logiczną wskazującą, czy zdarzenie zostało wykorzystane (tj. chcesz pominąć domyślne działanie). Jeśli zwróci wartość false
, oprócz zachowania niestandardowego pojawi się też domyślne zachowanie. Domyślnym działaniem dla zdarzenia kliknięcia znacznika jest wyświetlenie jego okna informacyjnego (jeśli jest dostępne) i przesunięcie kamery tak, aby znacznik był wyśrodkowany na mapie.
Wpływ Z-index na zdarzenia kliknięcia:
- Gdy użytkownik kliknie klaster znaczników, zdarzenie kliknięcia zostanie wywołane w przypadku znacznika o najwyższym kolejności nakładania elementów.
- Wywołuje się maksymalnie jedno zdarzenie na kliknięcie. Oznacza to, że kliknięcie nie jest przekazywane do znaczników ani innych nakładek o mniejszej kolejności nakładania elementów.
- Kliknięcie grupy znaczników powoduje kolejne kliknięcia w klastrze, które są kolejno zaznaczane. Kolejność uwzględnia przede wszystkim kolejność nakładania elementów, a następnie odległość od punktu kliknięcia.
- Jeśli użytkownik kliknie obszar znajdujący się w pobliżu klastra, interfejs API ponownie obliczy klaster i zresetuje stan cyklu kliknięcia, zaczynając od początku.
- Zdarzenie kliknięcia przechodzi przez kolejne znaczniki w różne znaczniki i nakładki.
- Znaczniki są jakby znajdowały się w osobnej grupie kolejności nakładania elementów w porównaniu z innymi nakładkami lub kształtami (linie, wielokąty, okręgi i nakładki na powierzchni ziemi) niezależnie od kolejności nakładania się pozostałych nakładek. Jeśli wiele znaczników, nakładek lub kształtów jest nałożonych na siebie, zdarzenie kliknięcia jest najpierw wyświetlane w grupie znaczników, a następnie wyzwalane dla innych nakładek lub kształtów, które można kliknąć, w zależności od wartości kolejności nakładania elementów.
Zdarzenia przeciągania znacznika
Za pomocą OnMarkerDragListener
możesz nasłuchiwać zdarzeń przeciągania na znaczniku. Aby ustawić ten detektor na mapie, wywołaj GoogleMap.setOnMarkerDragListener
. Aby przeciągnąć znacznik, użytkownik musi nacisnąć go długo. Gdy użytkownik przesuwa palec po ekranie, znacznik pozostaje w tym miejscu. Po przeciągnięciu znacznika onMarkerDragStart(Marker)
początkowo jest wywoływany. Podczas przeciągania znacznika onMarkerDrag(Marker)
jest wywoływany przez cały czas. Na końcu przeciągania jest wywoływana właściwość onMarkerDragEnd(Marker)
. W każdej chwili możesz sprawdzić położenie znacznika, dzwoniąc pod numer Marker.getPosition()
.