
Znaczniki identyfikują lokalizacje na mapie. Domyślny znacznik używa standardowej ikony, która jest zgodna z wyglądem i stylem Map Google. Za pomocą interfejsu API można zmienić kolor, obraz lub punkt kotwiczenia ikony. Znaczniki są obiektami typu
Marker i są dodawane do mapy za pomocą metody
GoogleMap.addMarker(markerOptions).
Znaczniki są interaktywne. Domyślnie odbierają zdarzenia click i są często używane z detektorami zdarzeń do wyświetlania okien
informacyjnych. Ustawienie właściwości draggable znacznika na true umożliwia użytkownikowi zmianę pozycji znacznika. Aby aktywować możliwość przesuwania znacznika, przytrzymaj go.
Domyślnie, gdy użytkownik kliknie znacznik, w prawym dolnym rogu mapy pojawi się pasek narzędzi mapy, który zapewnia szybki dostęp do aplikacji mobilnej Map Google. Możesz wyłączyć pasek narzędzi. Więcej informacji znajdziesz w przewodniku po elementach sterujących.
Dodawanie znacznika
W tym przykładzie pokazujemy, jak dodać znacznik do mapy. Znacznik jest tworzony we współrzędnych -33.852,151.211 (Sydney, Australia) i po kliknięciu wyświetla w oknie informacyjnym ciąg znaków „Marker in 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 znaczniku
Często trzeba wyświetlać dodatkowe informacje o miejscu lub lokalizacji, gdy użytkownik kliknie znacznik na mapie. Więcej informacji znajdziesz w przewodniku po oknach informacyjnych.
Powiązywanie danych ze znacznikiem
Za pomocą metody Marker.setTag() możesz przechowywać dowolny obiekt danych ze znacznikiem, a za pomocą metody Marker.getTag() możesz go pobrać. Poniższy przykład pokazuje, jak za pomocą tagów zliczać kliknięcia 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 je kliknie. Aby to zrobić, możesz zapisać ze znacznikiem ciąg znaków
Stringwskazujący jego typ. - Możesz korzystać z systemu, który ma unikalne identyfikatory rekordów, a znaczniki reprezentują konkretne rekordy w tym systemie.
- Dane znacznika mogą wskazywać priorytet, który ma być używany podczas określania kolejności nakładania znacznika.
Ustawianie znacznika jako przeciągalnego
Po dodaniu znacznika do mapy możesz zmienić jego położenie, o ile jego właściwość draggable jest ustawiona na true. Aby włączyć przeciąganie, przytrzymaj znacznik. Gdy odsuniesz palec od ekranu, znacznik pozostanie w tym miejscu.
Znaczniki nie są domyślnie przeciągalne. Musisz wyraźnie ustawić znacznik jako przeciągalny za pomocą metody MarkerOptions.draggable(boolean) przed dodaniem go do mapy lub za pomocą metody 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ągalny znacznik w 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, jak używać znaczników do wizualizacji lokalizacji na mapie.
Znaczniki mogą definiować niestandardowy obraz, który ma być wyświetlany zamiast ikony domyślnej. Definiowanie ikony polega na ustawieniu kilku właściwości, które wpływają na wizualne zachowanie znacznika.
Znaczniki obsługują dostosowywanie za pomocą tych właściwości:
- Pozycja (wymagana)
- Wartość
LatLngokreślająca położenie 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 dolnej części 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
- Bitmapa wyświetlana zamiast domyślnego obrazu znacznika.
- Element przeciągalny
- Ustaw na
truejeśli chcesz zezwolić użytkownikowi na przesuwanie znacznika. Domyślna wartość tofalse. - Widoczne
- Ustaw na
false, aby znacznik był niewidoczny. Domyślna wartość totrue. - Orientacja płaska lub billboardowa
- Domyślnie znaczniki używają orientacji billboardowej, co oznacza, że są rysowane w orientacji względem ekranu urządzenia, a nie powierzchni mapy. Obracanie, przechylanie lub powiększanie mapy nie zmienia orientacji znacznika. Możesz ustawić orientację znacznika tak, aby był płaski względem ziemi. Płaskie znaczniki obracają się, gdy mapa jest obracana, i zmieniają perspektywę, gdy mapa jest przechylana. Podobnie jak w przypadku znaczników billboardowych, płaskie znaczniki zachowują swój rozmiar, gdy mapa jest powiększana lub pomniejszana.
- Obrót
- Orientacja znacznika podana w stopniach zgodnie z ruchem wskazówek zegara. Pozycja domyślna zmienia się, jeśli znacznik jest płaski. Domyślna pozycja płaskiego znacznika jest wyrównana do północy. Gdy znacznik nie jest płaski, jego domyślna pozycja jest skierowana do góry, a obrót jest taki, że znacznik jest zawsze skierowany w stronę kamery.
Poniższy fragment kodu tworzy prosty znacznik z ikoną domyślną.
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żesz dostosować kolor domyślnego obrazu znacznika, przekazując obiekt BitmapDescriptor do metody icon(). Możesz użyć zestawu predefiniowanych kolorów w obiekcieBitmapDescriptorFactory lub ustawić znacznik niestandardowy za pomocą metodyBitmapDescriptorFactory.defaultMarker(float hue). Odcień to wartość z zakresu od 0 do 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
Możesz kontrolować przezroczystość znacznika za pomocą metody MarkerOptions.alpha(). Wartość alfa powinna być określona jako liczba zmiennoprzecinkowa z zakresu od 0,0 do 1,0, gdzie 0 oznacza pełną przezroczystość, a 1 – pełną nieprzezroczystość.
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 obrazem znacznika niestandardowego, często nazywanym ikoną. Ikony niestandardowe są zawsze ustawiane jako BitmapDescriptor i definiowane za pomocą jednej z metod w BitmapDescriptorFactory klasie.
fromAsset(String assetName)- Tworzy niestandardowy znacznik, używając nazwy obrazu bitmapowego w katalogu zasobów.
fromBitmap(Bitmap image)- Tworzy niestandardowy znacznik z obrazu bitmapowego.
fromFile(String fileName)- Tworzy ikonę niestandardową, używając nazwy pliku obrazu bitmapowego znajdującego się w pamięci wewnętrznej.
fromPath(String absolutePath)- Tworzy niestandardowy znacznik z bezwzględnej ścieżki pliku obrazu bitmapowego.
fromResource(int resourceId)- Tworzy niestandardowy znacznik, używając identyfikatora zasobu obrazu bitmapowego.
Poniższy fragment kodu tworzy znacznik z ikoną niestandardową.
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 rysowane względem ekranu. Obracanie, przechylanie lub powiększanie mapy nie zmienia orientacji znacznika. Możesz ustawić orientację znacznika tak, aby był płaski względem ziemi. Znaczniki zorientowane w ten sposób będą się obracać, gdy mapa jest obracana, i zmieniać perspektywę, gdy mapa jest przechylana. Płaskie znaczniki zachowują swój rozmiar, gdy mapa jest powiększana lub pomniejszana.
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ół jego punktu kotwiczenia za pomocą metody Marker.setRotation(). Obrót jest mierzony w stopniach zgodnie z ruchem wskazówek zegara od pozycji domyślnej. Gdy znacznik jest płaski na mapie, jego domyślna pozycja to północ. Gdy znacznik nie jest płaski, jego domyślna pozycja jest skierowana do góry, a obrót jest taki, że znacznik jest zawsze skierowany w stronę kamery.
Poniższy przykład obraca znacznik o 90°. Ustawienie punktu kotwiczenia na 0.5,0.5 powoduje, że znacznik jest obracany wokół ś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));
Kolejność nakładania znacznika
Kolejność nakładania określa kolejność nakładania tego znacznika względem innych znaczników na mapie. Znacznik o wysokiej kolejności nakładania jest rysowany nad znacznikami o niższej kolejności nakładania. Domyślna wartość kolejności nakładania to 0.
Ustaw kolejność nakładania w obiekcie opcji znacznika, wywołując metodę 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));
Możesz uzyskać dostęp do kolejności nakładania znacznika, wywołując metodę Marker.getZIndex(), a możesz ją zmienić, wywołując metodę Marker.setZIndex().
Znaczniki są zawsze rysowane nad warstwami kafelków i innymi nakładkami innymi niż znaczniki (nakładki na ziemię, polilinie, wielokąty i inne kształty) niezależnie od kolejności nakładania innych nakładek. Znaczniki są traktowane jako należące do oddzielnej grupy kolejności nakładania w porównaniu z innymi nakładkami.
Poniżej znajdziesz informacje o wpływie kolejności nakładania na zdarzenia kliknięcia .
Obsługa zdarzeń znacznika
Interfejs API Map Google umożliwia nasłuchiwanie zdarzeń znacznika i reagowanie na nie. Aby nasłuchiwać tych zdarzeń, musisz ustawić odpowiedni detektor w obiekcie GoogleMap, do którego należą znaczniki. Gdy zdarzenie wystąpi na jednym ze znaczników na mapie, wywołanie zwrotne detektora zostanie wywołane z odpowiednim obiektem Marker przekazanym jako parametr. Aby porównać ten obiekt Marker z własnym odwołaniem do obiektu Marker, musisz użyć metody equals() zamiast operatora ==.
Możesz nasłuchiwać tych zdarzeń:
- Zdarzenia kliknięcia znacznika
- Zdarzenia przeciągania znacznika
- Zdarzenia kliknięcia okna informacyjnego
Zdarzenia kliknięcia znacznika
Aby nasłuchiwać zdarzeń kliknięcia znacznika, możesz użyć interfejsu OnMarkerClickListener do nasłuchiwania
zdarzeń kliknięcia znacznika. Aby ustawić ten detektor na mapie, wywołaj metodę GoogleMap.setOnMarkerClickListener(OnMarkerClickListener). Gdy użytkownik kliknie znacznik, zostanie wywołana metoda onMarkerClick(Marker), a znacznik zostanie przekazany jako argument. Ta metoda zwraca wartość logiczną wskazującą, czy zdarzenie zostało przez Ciebie wykorzystane (tzn. czy chcesz pominąć domyślne zachowanie). Jeśli zwróci false, oprócz Twojego niestandardowego zachowania wystąpi też zachowanie domyślne. Domyślne zachowanie w przypadku zdarzenia kliknięcia znacznika
polega na wyświetleniu jego okna informacyjnego (jeśli jest dostępne) i przesunięciu
kamery tak, aby znacznik był wyśrodkowany na mapie.
Wpływ kolejności nakładania na zdarzenia kliknięcia:
- Gdy użytkownik kliknie klaster znaczników, zdarzenie kliknięcia zostanie wywołane dla znacznika o najwyższej kolejności nakładania.
- Na kliknięcie jest wywoływane co najwyżej 1 zdarzenie. Innymi słowy, kliknięcie nie jest przekazywane do znaczników ani innych nakładek o niższej kolejności nakładania.
- Kliknięcie klastra znaczników powoduje, że kolejne kliknięcia przechodzą przez klaster, wybierając kolejno każdy znacznik. Kolejność cyklu najpierw uwzględnia kolejność nakładania, a potem odległość od punktu kliknięcia.
- Jeśli użytkownik kliknie poza zasięgiem klastra, interfejs API ponownie obliczy klaster i zresetuje stan cyklu kliknięcia, aby rozpocząć go od początku.
- Znaczniki są traktowane jako należące do oddzielnej grupy kolejności nakładania w porównaniu z innymi nakładkami lub kształtami (polilinie, wielokąty, okręgi i/lub nakładki na ziemię) niezależnie od kolejności nakładania innych nakładek. Jeśli kilka znaczników, nakładek lub kształtów nakłada się na siebie, zdarzenie kliknięcia jest najpierw przekazywane przez klaster znaczników.
Zdarzenia przeciągania znacznika
Aby nasłuchiwać
zdarzeń przeciągania znacznika, możesz użyć interfejsu OnMarkerDragListener. Aby ustawić ten detektor na mapie, wywołaj metodę GoogleMap.setOnMarkerDragListener. Aby przeciągnąć znacznik, użytkownik musi go przytrzymać. Gdy użytkownik odsunie palec od ekranu, znacznik pozostanie w tym miejscu. Gdy znacznik jest przeciągany, początkowo wywoływana jest metoda onMarkerDragStart(Marker). Podczas przeciągania znacznika metoda onMarkerDrag(Marker) jest wywoływana nieustannie. Na końcu przeciągania wywoływana jest metoda onMarkerDragEnd(Marker). W dowolnym momencie możesz uzyskać pozycję znacznika, wywołując metodę Marker.getPosition().