Komponen Penanda Tempat
Komponen Penanda Tempat memungkinkan Anda membuat anotasi peta yang dapat disesuaikan yang menampilkan informasi Tempat utama langsung di peta. Anda dapat menampilkan konten seperti rating tempat, jenis tempat, status buka atau tutup, rentang harga, atau teks kustom (misalnya, label buatan AI atau nomor rencana perjalanan). Hal ini memberikan pengalaman eksplorasi peta yang lebih informatif kepada pengguna Anda tanpa mengharuskan mereka mengetuk kartu tempat yang mendetail.
Anda dapat menampilkan satu ikon penanda dan teks penanda opsional per PlaceMarker.
Ikon yang tersedia adalah:
Type: Jenis tempat.None: Tidak ada ikon.
Rating: Skor rating.PriceRange: Rentang harga (misalnya, Rp100.000-200.000).OpenStatus: Apakah bisnis buka atau tutup.Custom: Teks kustom (misalnya, "POPULER").
Referensi tempat menggunakan ID Tempat (PlaceId), Nama resource (ResourceName), atau koordinat geografis (Coordinates).
Persyaratan tampilan dan atribusi
Saat penanda peta Places UI Kit ditampilkan, penanda tidak boleh muncul secara terpisah. Komponen ini harus interaktif dan membuka Komponen Detail Tempat atau Lightbox terkait saat diklik atau diketuk untuk memberikan branding Google, atribusi kontributor, dan alur Laporkan Masalah yang diperlukan.
Lihat persyaratan atribusi foto dan ulasan kami untuk skenario saat ruang terbatas.
Contoh Penanda Tempat
Kami menyediakan fungsi @Composable Jetpack Compose untuk menghilangkan overhead wrapper View-to-Compose dan menghindari masalah ketidakcocokan tema.
Penyesuaian penanda dasar
Contoh kode berikut menunjukkan penyesuaian penanda tempat dasar, termasuk menyembunyikan ujung balon ucapan segitiga untuk penanda default.
Kotlin
import androidx.compose.runtime.Composable import com.google.android.libraries.places.compose.PlaceMarker import com.google.android.libraries.places.compose.marker.MarkerIcon import com.google.android.libraries.places.compose.marker.MarkerText import com.google.android.libraries.places.compose.PlaceReference @Composable fun DefaultMarker() { PlaceMarker( reference = PlaceReference.PlaceId("PLACE_ID"), icon = MarkerIcon.None, beakPresence = false, // remove beak ) } @Composable fun RatingMarker() { PlaceMarker( reference = PlaceReference.PlaceId("PLACE_ID"), icon = MarkerIcon.None, text = MarkerText.Rating ) } @Composable fun TypeAndRatingMarker() { PlaceMarker( reference = PlaceReference.PlaceId("PLACE_ID"), icon = MarkerIcon.Type, text = MarkerText.Rating ) } @Composable fun PriceRangeMarker() { PlaceMarker( reference = PlaceReference.ResourceName("places/PLACE_RESOURCE_NAME"), icon = MarkerIcon.None, text = MarkerText.PriceRange ) } @Composable fun OpenStatusMarker() { PlaceMarker( reference = PlaceReference.Coordinates(latitude = 37.7749, longitude = -122.4194), icon = MarkerIcon.None, text = MarkerText.OpenStatus ) } @Composable fun CustomTextMarker() { PlaceMarker( reference = PlaceReference.PlaceId("PLACE_ID"), icon = MarkerIcon.None, // Custom text accepts a String to display a number (e.g. "3") or text (e.g. "NEW") text = MarkerText.Custom("NEW") ) }
Membuat pemroses klik
Anda dapat memberikan callback onClick untuk memicu tindakan kustom saat penanda mandiri diketuk. Namun, saat penanda dirender di peta (misalnya, di dalam MarkerComposable), peristiwa ketuk dicegat oleh peta. Dalam hal ini, Anda harus menggunakan handler onClick MarkerComposable, bukan penanda.
Contoh kode berikut menunjukkan cara menggunakan handler onClick MarkerComposable.
Kotlin
import android.util.Log import androidx.compose.runtime.Composable import com.google.android.libraries.places.compose.PlaceMarker import com.google.android.libraries.places.compose.marker.MarkerIcon import com.google.android.libraries.places.compose.PlaceReference /** * PlaceMarker used outside of a map (e.g. in a list, bottom sheet, or custom overlay). * * There is no host component that provides a default click behavior here, so PlaceMarker's own * `onClick` is the only way for a developer to react to a tap. This is why `onClick` must stay * on the PlaceMarker API. */ @Composable fun ClickableMarkerWithCustomConfig() { PlaceMarker( reference = PlaceReference.PlaceId("PLACE_ID"), icon = MarkerIcon.Type, onClick = { place -> openPlaceCard(place.id) // developer might want to open the place card Log.i("PlacesMarker", "Marker was tapped by user!") } ) } /** * PlaceMarker used as the content of a MarkerComposable on a GoogleMap. * * MarkerComposable does NOT add PlaceMarker to the touch-input hierarchy: it snapshots the * composable into a bitmap and hands that bitmap to the Maps renderer as the marker icon. The * rendered marker is a map object, not a Compose node, so: * * - PlaceMarker's own `onClick` would never be invoked here (no touch events ever reach it). * - The tap is delivered by the Maps SDK to MarkerComposable's `onClick`, which is the only * click entry point on a map. * * Accordingly, the state-based `PlaceMarker(state = ...)` overload used below deliberately does * not expose an `onClick` parameter, so the correct handler is the only one available. */ @Composable fun PlaceMarkerOnMap(markerState: PlaceMarkerState) { GoogleMap( modifier = Modifier.fillMaxSize(), cameraPositionState = rememberCameraPositionState(), ) { markerState.location?.let { position -> MarkerComposable( state = rememberUpdatedMarkerState(position = position), // this is the click handler for the map use case. onClick = { markerState.place?.let { place -> openPlaceCard(place.id) } true // consume the event }, ) { PlaceMarker(state = markerState) } } } }
Menangani status pemuatan dan callback
Contoh kode berikut menunjukkan cara menyediakan callback untuk menangani error rendering atau data yang tidak ada.
Kotlin
import android.util.Log import androidx.compose.runtime.Composable import com.google.android.libraries.places.compose.PlaceMarker import com.google.android.libraries.places.compose.marker.MarkerIcon import com.google.android.libraries.places.compose.PlaceReference @Composable fun StatusHandlingMarker() { PlaceMarker( reference = PlaceReference.PlaceId("PLACE_ID"), icon = MarkerIcon.Type, // Triggered when attribute data is successfully fetched and the marker is rendered. // Returns a minimal Place object with ID, location (LatLng), and viewport fields set. onMarkerLoaded = { place -> Log.i("PlacesMarker", "Marker successfully loaded for place ID: ${place.id}") }, // Triggered when data fetching fails or required attribute data is missing for the place. // Returns an optional Place object and an Exception describing the root cause. onMarkerLoadFailed = { place, exception -> Log.e("PlacesMarker", "Failed to load marker for place ID: ${place?.id}", exception) } ) }
Menggunakan PlaceMarkerState untuk menempatkan penanda di peta
Objek Place ditampilkan dengan lokasi dan area tampilan untuk membantu Anda memutuskan tempat untuk meletakkan penanda.
Kotlin
// Step 1: Obtain configured handle in a single 1-line call (PlaceMarker mounted internally) val markerState = rememberPlaceMarkerState( reference = PlaceReference.PlaceId(placeId), icon = MarkerIcon.Type ) // Step 2: Pass PlaceMarkerState.location and PlaceMarker(state = PlaceMarkerState) directly to the map marker GoogleMap(...) { markerState.location?.let { position -> MarkerComposable( state = rememberMarkerState(position = position), onClick = { markerState.place?.let { place -> // Handle marker click } true } ) { PlaceMarker(state = markerState) // Render marker UI content directly on map canvas } } }
Menskalakan penanda ke ukuran kustom
Kotlin
// Off the map: scale with a one-line modifier. // Modifier.scale is a draw-time transform, so the bubble, beak, icon and text all scale together. @Composable fun ScaledMarker() { PlaceMarker( reference = PlaceReference.PlaceId(placeId), icon = MarkerIcon.Type, text = MarkerText.Rating, modifier = Modifier.scale(2.1f), ) } // On the map: scale by overriding LocalDensity. // MarkerComposable snapshots its content into a marker bitmap sized to the measured layout bounds. // Modifier.scale does not change those bounds, so the marker would be clipped and blurry. Scaling // the density re-measures every dp and sp inside the marker, so the bitmap, the layout bounds and // the map hit target all grow with it. @Composable fun ScaledMarkerOnMap(markerState: PlaceMarkerState) { val density = LocalDensity.current val scaledDensity = remember(density) { Density(density = density.density * 2.1f, fontScale = density.fontScale * 2.1f) } GoogleMap(...) { markerState.location?.let { position -> MarkerComposable( state = rememberUpdatedMarkerState(position = position), anchor = Offset(0.5f, 1.0f), ) { CompositionLocalProvider(LocalDensity provides scaledDensity) { PlaceMarker(state = markerState) } } } } }