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. Zapoznaj się z samouczkiem dotyczącym dodawania mapy za pomocą znacznika.
- 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. Przytrzymaj, by aktywować możliwość
przesunięcia znacznika.
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 zostanie utworzony w miejscu o współrzędnych -33.852,151.211
(Sydney, Australia) i po kliknięciu wyświetla ciąg „Marker in Sydney” w oknie informacyjnym.
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świetl dodatkowe informacje o znaczniku
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 warto przechowywać i pobierać dane 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. W tym celu możesz zapisać obiekt
String
ze znacznikiem wskazującym typ. - Być może korzystasz z systemu z unikalnymi identyfikatorami 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 jest przeciągalny, 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
pozycji znacznika na mapie. 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 znaków wyświetlany w oknie informacyjnym, gdy użytkownik kliknie znacznik.
- 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
, by znacznik był niewidoczny. 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 mapie. Obracanie, przechylanie i powiększanie mapy nie zmienia orientacji znacznika. Możesz ustawić płaską orientację znacznika względem ziemi. Płaskie znaczniki obracają się, gdy mapa jest obrócona, i zmieniają perspektywę, gdy jest przechylona. Tak jak w przypadku znaczników billboardów, płaskie znaczniki zachowują swój rozmiar po powiększeniu lub pomniejszeniu 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
Można dostosować kolor domyślnego obrazu znacznika, przekazując obiekt BitmapDescriptor
do metody icon(). 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
Przezroczystość znacznika można kontrolować za pomocą metody MarkOptions.alpha(). 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 na podstawie nazwy obrazu bitmapy z katalogu zasobów.
fromBitmap(Bitmap image)
- Tworzy niestandardowy znacznik na podstawie obrazu typu bitmapa.
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 kolejność nakładania elementów w obiekcie opcji znacznika, wywołując funkcję MarkerOptions.zIndex()
w sposób podany 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 w jednym ze znaczników na mapie, wywołanie zwrotne detektora zostanie wywołane 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
- Zdarzenia przeciągania znacznika
- Zdarzenia kliknięcia okna z informacjami
Zdarzenia kliknięcia znacznika
Możesz użyć OnMarkerClickListener
, aby nasłuchiwać zdarzeń kliknięć znacznika. 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
, spowoduje to dodatkowe działanie domyślne. 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 ustawienia z-index 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 wyzwalane jest 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. W kolejności cyklu uwzględnia się najpierw kolejność, a później odległość do 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. W przypadku nałożenia na siebie wielu znaczników, nakładek lub kształtów zdarzenie kliknięcia jest najpierw cyklicznie wskazywane przez grupę znaczników, a następnie jest wywoływane dla innych klikalnych nakładek lub kształtów na podstawie ich wartości z-index.
zdarzenia przeciągania znacznika;
Za pomocą OnMarkerDragListener
możesz nasłuchiwać zdarzeń przeciągania ze znacznika. Aby ustawić tego słuchacza na mapie, wywołaj funkcję GoogleMap.setOnMarkerDragListener
. Aby przeciągnąć znacznik, użytkownik musi go
przytrzymać. 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 przeciągania jest wywoływana funkcja onMarkerDragEnd(Marker)
. Pozycję znacznika możesz uzyskać w dowolnym momencie, wywołując funkcję Marker.getPosition()
.