Znaczniki wskazują pojedyncze lokalizacje na mapie. Możesz dostosować znaczniki, zmieniając domyślny kolor lub zastępując ikonę niestandardowym obrazem. Okna z informacjami mogą zawierać dodatkowy kontekst dotyczący znacznika.
Przykładowe fragmenty kodu
Repozytorium ApiDemos na GitHubie zawiera przykład, który demonstruje różne funkcje znacznika:
Kotlin
- MapWithMarker: prosta mapa ze znacznikiem. Zobacz samouczek dotyczący dodawania mapy ze znacznikiem KT.
- MarkerDemoActivity: używanie znaczników na mapie, w tym opcji i detektorów
Java
- MapWithMarker: prosta mapa ze znacznikiem. Zobacz samouczek dotyczący dodawania mapy ze znacznikiem.
- MarkerDemoActivity: używanie znaczników na mapie, w tym opcji i detektorów
Wprowadzenie
Znaczniki wskazują miejsca na mapie. Domyślny znacznik używa standardowego ikony, która jest wspólna dla wyglądu i stylu Map Google. Za pomocą interfejsu API możesz zmienić kolor, obraz lub punkt kotwiczenia ikony. Znaki są obiektami typu Marker
i są dodawane do mapy za pomocą metody GoogleMap.addMarker(markerOptions)
.
znaczniki są interaktywne; Domyślnie otrzymują one zdarzenia click
i są często używane z detektorami zdarzeń do wyświetlania okien informacji. Ustawienie właściwości draggable
na true
pozwala użytkownikowi zmienić pozycję znacznika. Aby aktywować możliwość przeciągania znacznika, naciśnij i przytrzymaj.
Domyślnie, gdy użytkownik kliknie znacznik, w prawym dolnym rogu mapy pojawi się pasek narzędzi mapy, który umożliwia szybki dostęp do aplikacji mobilnej Mapy Google. Pasek narzędzi możesz wyłączyć. Więcej informacji znajdziesz w przewodniku po elementach sterujących.
Pierwsze kroki ze znacznikami
W tym odcinku Maps Live omawiamy podstawy dodawania znaczników do mapy za pomocą pakietu Maps SDK na Androida.
Dodaj znacznik
Ten przykład pokazuje, jak dodać znacznik do mapy. Znacznik jest tworzony na współrzędnych -33.852,151.211
(Sydney, Australia) i po kliknięciu wyświetla w oknie informacyjnym ciąg znaków „Znacznik w 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)) }
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)); }
Wyświetlanie dodatkowych informacji o oznaczniku
Typowym wymaganiem jest wyświetlanie dodatkowych informacji o miejscu lub lokalizacji po kliknięciu przez użytkownika znacznika na mapie. Zapoznaj się z przeglądaniem okien informacyjnych.
Powiązanie danych ze znacznikiem
Możesz przechowywać dowolny obiekt danych z markerem za pomocą funkcji Marker.setTag()
, a odzyskiwać obiekt danych za pomocą funkcji Marker.getTag()
. Przykład poniżej pokazuje, jak za pomocą tagów zliczać liczbę kliknięć znacznika:
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; } }
Oto kilka przykładów sytuacji, w których przydatne jest przechowywanie i pobieranie danych za pomocą znaczników:
- Twoja aplikacja może obsługiwać różne typy znaczników i chcesz je traktować inaczej, gdy użytkownik kliknie jeden z nich. Aby to zrobić, możesz przechowywać wartość
String
z oznacznikiem wskazującym typ. - Możesz mieć do czynienia z systemem, który ma unikalne identyfikatory rekordów, gdzie znaczniki reprezentują konkretne rekordy w tym systemie.
- Dane znacznika mogą wskazywać priorytet, który ma być używany przy określaniu indeksu z znacznika.
Ustawianie znacznika jako przeciąganego
Po dodaniu znacznika do mapy możesz zmienić jego położenie, o ile tylko właściwość draggable
jest ustawiona na true
. Naciśnij i przytrzymaj znacznik, aby umożliwić przeciąganie. Gdy odłączysz palec od ekranu, znacznik pozostanie w tej pozycji.
Domyślnie znaczniki nie są przeciągane. Musisz wyraźnie ustawić, że znacznik ma być przeciągany, albo za pomocą MarkerOptions.draggable(boolean)
przed dodaniem go do mapy, albo za pomocą Marker.setDraggable(boolean)
po dodaniu go do mapy.
Możesz nasłuchiwać zdarzeń przeciągania znacznika, jak opisano w sekcji Zdarzenia przeciągania znacznika.
Poniższy fragment kodu dodaje przeciągany znacznik do Perth w Australii.
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));
Dostosowywanie znacznika
Ten film pokazuje sposoby wizualizacji lokalizacji na mapie za pomocą znaczników.
Markery mogą zawierać niestandardowy obraz, który będzie wyświetlany zamiast domyślnej ikony. Definiowanie ikony wymaga ustawienia kilku właściwości, które wpływają na zachowanie wizualne znacznika.
Znaczniki obsługują dostosowywanie za pomocą tych właściwości:
- Pozycja (wymagana)
- Wartość
LatLng
dla położenia znacznika na mapie. Jest to jedyna wymagana właściwość obiektuMarker
. - Kotwica
- Punkt na obrazie, który zostanie umieszczony w pozycji LatLng znacznika. Domyślnie jest to środek dołu obrazu.
- Alfa
- Ustawia przezroczystość znacznika. Domyślna wartość to 1,0.
- Tytuł
- Ciąg tekstowy wyświetlany w oknie informacyjnym po kliknięciu przez użytkownika znacznika.
- Krótki opis
- Dodatkowy tekst wyświetlany pod tytułem.
- Ikona
- Plik mapy bitowej wyświetlany zamiast domyślnego obrazu znacznika.
- Przeciąganie
- Ustaw na
true
, jeśli chcesz zezwolić użytkownikowi na przenoszenie znacznika. Domyślna wartość tofalse
. - Widoczne
- Ustaw na
false
, aby ukryć znacznik. Domyślna wartość totrue
. - Orientacja pozioma lub pionowa
- Domyślnie znaczniki mają orientację billboardową, co oznacza, że są one wyświetlane na ekranie urządzenia, a nie na powierzchni mapy. Obracanie, przechylanie i powiększanie mapy nie zmienia orientacji znacznika. Możesz ustawić orientację znacznika tak, aby był płaski na powierzchni Ziemi. Płaskie znaczniki obracają się, gdy obracasz mapę, i zmieniają perspektywę, gdy ją przechylisz. Podobnie jak w przypadku znaczników typu billboard, znaczniki płaskie zachowują swój rozmiar podczas powiększania lub pomniejszania mapy.
- Obrót
- Orientacja znacznika określona w stopniach w kierunku ruchu wskazówek zegara. Domyślna pozycja zmienia się, jeśli znacznik jest płaski. Domyślna pozycja płaskiego znacznika to kierunek na północ. Gdy znacznik nie jest płaski, jego domyślna pozycja jest skierowana w górę, a obrócenie jest takie, że znacznik jest zawsze skierowany w kierunku kamery.
Podany niżej fragment kodu tworzy prosty znacznik z domyślną ikoną.
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));
Dostosowywanie koloru znacznika
Kolor obrazu znacznika domyślnego można dostosować, przekazując do metody icon() obiekt BitmapDescriptor
. Możesz użyć zestawu wstępnie zdefiniowanych kolorów w obiekcie BitmapDescriptorFactory
lub ustawić niestandardowy kolor znacznika za pomocą metody BitmapDescriptorFactory.defaultMarker(float hue)
. Barwa to wartość z zakresu 0–360, która reprezentuje punkty na kole kolorów.
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)));
Dostosowywanie przezroczystości znacznika
Za pomocą metody MarkerOptions.alpha() możesz kontrolować przezroczystość znacznika. Wartość alfa powinna być podana jako liczba zmiennoprzecinkowa z zakresu od 0,0 do 1,0, gdzie 0 oznacza całkowitą przezroczystość, a 1 – całkowity brak przezroczystości.
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));
Dostosowywanie obrazu znacznika
Możesz zastąpić domyślny obraz znacznika niestandardowym obrazem znacznika, który często nazywany jest ikoną. Ikony niestandardowe są zawsze ustawiane jako BitmapDescriptor
i definiowane za pomocą jednej z metod w klasie BitmapDescriptorFactory
.
fromAsset(String assetName)
- Tworzy znacznik niestandardowy za pomocą nazwy obrazu typu Bitmap w katalogu Assets.
fromBitmap(Bitmap image)
- Tworzy niestandardowy znacznik na podstawie obrazu bitmapowego.
fromFile(String fileName)
- Tworzy ikonę niestandardową na podstawie nazwy pliku obrazu typu Bitmap znajdującego się w pamięci wewnętrznej.
fromPath(String absolutePath)
- Tworzy znacznik niestandardowy na podstawie bezwzględnej ścieżki do pliku obrazu typu Bitmap.
fromResource(int resourceId)
- Tworzy znacznik niestandardowy za pomocą identyfikatora zasobu obrazu typu Bitmap.
Poniżej znajduje się fragment kodu, który tworzy znacznik z niestandardową ikoną.
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)));
Spłaszczanie znacznika
Ikony znaczników są zwykle wyświetlane względem ekranu. Obracanie, przechylanie lub powiększanie mapy nie zmienia orientacji znacznika. Możesz ustawić orientację znacznika tak, aby był płaski na Ziemi. Znaczniki o takim ułożeniu będą się obracać, gdy obróci się mapę, i zmieniać perspektywę, gdy ją przechyli. Płaskie znaczniki zachowują swój rozmiar podczas powiększania lub pomniejszania mapy.
Aby zmienić orientację znacznika, ustaw jego właściwość flat
na 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));
Obracanie znacznika
Możesz obracać znacznik wokół punktu zakotwiczenia za pomocą przycisku Marker
.setRotation()
metody. Obrót jest mierzony w stopniach zgodnie z ruchem wskazówek zegara względem pozycji domyślnej. Gdy znacznik jest płaski na mapie, domyślną pozycją jest północ. Gdy znacznik nie jest płaski, jego domyślna pozycja jest skierowana w górę, a obrócenie jest takie, że znacznik jest zawsze skierowany w kierunku kamery.
W przykładzie poniżej znacznik jest obracany o 90°. Ustawienie punktu kotwiczenia na 0.5,0.5
powoduje, że znacznik jest obracany wokół swojego środka, a nie podstawy.
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 znacznika
Indeks Z określa kolejność nakładania tego znacznika względem innych znaczników na mapie. znacznik o wysokiej wartości wskaźnika z-index jest narysowany na wierzchu znaczników o niższej wartości tego wskaźnika; Wartością domyślną z-index jest 0
.
Ustaw indeks Z obiektu opcji znacznika, wywołując funkcję MarkerOptions.zIndex()
, jak pokazano w tym fragmencie kodu:
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));
Aby uzyskać dostęp do indeksu Z znacznika, wywołaj funkcję Marker.getZIndex()
, a aby go zmienić, wywołaj funkcję Marker.setZIndex()
.
znaczniki są zawsze wyświetlane nad warstwami płytek i innymi nakładkami (nakładkami na grunt, poliliniami, wielokątami i innymi kształtami) niezależnie od z-indeksu innych nakładek. W porównaniu z innymi nakładkami znaczniki są traktowane jako należące do osobnej grupy indeksu Z.
Poniżej znajdziesz informacje o wpływie indeksu Z na zdarzenia kliknięcia.
Obsługa zdarzeń znacznika
Interfejs Maps API umożliwia nasłuchiwanie zdarzeń znacznika i reagowanie na nie. Aby nasłuchiwać te zdarzenia, musisz ustawić odpowiedni detektor w obiekcie GoogleMap
, do którego należą znaczniki. Gdy zdarzenie wystąpi na jednym ze znaczników na mapie, zostanie wywołane wywołanie zwrotne detektora z odpowiednim obiektem Marker
przekazanym 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
- Zdarzenia przeciągania znacznika
- Zdarzenia kliknięcia okna z informacjami
Zdarzenia kliknięcia znacznika
Możesz użyć tagu OnMarkerClickListener
, aby nasłuchiwać zdarzeń kliknięcia na znaczniku. Aby ustawić tego słuchacza na mapie, wywołaj funkcję GoogleMap.setOnMarkerClickListener(OnMarkerClickListener)
. Gdy użytkownik kliknie znacznik, zostanie wywołana metoda onMarkerClick(Marker)
, a znacznik zostanie przekazany jako argument. Zwraca ona wartość logiczną wskazującą, czy zdarzenie zostało już wykorzystane (czyli czy chcesz zablokować domyślne zachowanie). Jeśli zwróci wartość false
, działanie domyślne zostanie wykonane oprócz działania niestandardowego. Domyślne zachowanie zdarzenia kliknięcia znacznika polega na wyświetleniu okna z informacjami (jeśli jest dostępne) i przesunięciu kamery tak, aby znacznik znalazł się na środku mapy.
Wpływ indeksu Z na zdarzenia kliknięcia:
- Gdy użytkownik kliknie grupę znaczników, zostanie wywołane zdarzenie kliknięcia dla znacznika o najwyższym indeksie z.
- Na każde kliknięcie może być wywoływane maksymalnie 1 zdarzenie. Inaczej mówiąc, kliknięcie nie jest przekazywane do markerów ani innych nakładek o niższej wartości Kolejności nakładania elementów.
- Kliknięcie grupy znaczników powoduje, że kolejne kliknięcia będą przełączać się między elementami w grupie. Kolejność cyklu jest ustalana według priorytetów: najpierw z-index, a potem odległość od punktu kliknięcia.
- Jeśli użytkownik kliknie poza obszarem klastra, interfejs API ponownie obliczy klaster i zresetuje stan cyklu kliknięć, aby rozpoczął się od początku.
- Zdarzenie kliknięcia przechodzi przez grupy znaczników do innych kształtów i nakładek, a potem uruchamia cykl od nowa.
- W porównaniu z innymi nakładkami lub kształtami (polilinia, wielokąty, koła lub nakładki na grunt) znaczniki są traktowane jako należące do osobnej grupy indeksu z, niezależnie od indeksu z innych nakładek. Jeśli na siebie nakładają się liczne znaczniki, nakładki lub kształty, zdarzenie kliknięcia jest najpierw wywoływane przez grupę znaczników, a potem przez inne klikalne nakładki lub kształty na podstawie ich wartości indeksu Z.
zdarzenia przeciągania znacznika;
Możesz użyć OnMarkerDragListener
, aby nasłuchiwać zdarzeń przeciągania znacznika. Aby ustawić tego słuchacza na mapie, wywołaj funkcję GoogleMap.setOnMarkerDragListener
. Aby przeciągnąć znacznik, użytkownik musi nacisnąć go dłużej. Gdy użytkownik odsunie palec od ekranu, znacznik pozostanie w tej pozycji. Gdy przeciągasz znacznik, początkowo wywoływana jest funkcja onMarkerDragStart(Marker)
. Podczas przeciągania znacznika funkcja onMarkerDrag(Marker)
jest stale wywoływana. Na końcu funkcji przeciągania wywoływana jest funkcja onMarkerDragEnd(Marker)
. Pozycję znacznika możesz uzyskać w dowolnym momencie, wywołując funkcję Marker.getPosition()
.