Componente Place Details avanzato
La versione Advanced del componente Place Details offre le stesse funzionalità di Places Details Essentials. Inoltre, ti consente di configurare i pulsanti di azione del componente e di applicare opzioni di ricerca e filtro alle recensioni e ai contenuti multimediali visualizzati.
Supporto integrato di Jetpack Compose
Places UI Kit fornisce funzioni @Composable di Jetpack Compose per AdvancedPlaceDetailsCompact. Questi componibili utilizzano lo stato con hoisting, il supporto dei modificatori integrato e i DSL degli slot nativi di Compose.
Il seguente esempio di codice mostra come utilizzare la funzione componibile per un layout verticale.
Kotlin
import android.util.Log import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.unit.dp import com.google.android.libraries.places.api.model.Place import com.google.android.libraries.places.compose.AdvancedPlaceDetailsCompact import com.google.android.libraries.places.compose.PlaceReference import com.google.android.libraries.places.compose.action.CornerAction import com.google.android.libraries.places.compose.action.MainAction import com.google.android.libraries.places.compose.Orientation @Composable fun SampleAdvancedPlaceDetailsCompactCard( placeId: String, bookmarkIcon: Painter, onSavePlaceClicked: (Place) -> Unit ) { AdvancedPlaceDetailsCompact( // defines the place to be displayed reference = PlaceReference.PlaceId(placeId), // defines the orientation orientation = Orientation.VERTICAL, // defines custom styling modifier = Modifier .fillMaxWidth() .padding(16.dp), preferTruncation = true, enableLightbox = true, mainActions = { place -> listOf( MainAction.OpenDirections(), MainAction.OpenWebsite(), MainAction.Call() ) }, // action button configuration cornerActions = { place -> listOf( CornerAction.Custom( icon = bookmarkIcon, text = "Save Place", onClick = { onSavePlaceClicked(place) } ) ) }, onPlaceLoaded = { place -> Log.d("Places", "Successfully loaded place: ${place.id}") }, onPlaceLoadFailed = { exception -> Log.e("Places", "Failed to load place", exception) } ) { // --- Slot: Injected directly above the place name --- basicSectionTop { Text( text = "Featured in 'Top 10 Coffee Shops in SF'", style = MaterialTheme.typography.labelSmall, color = MaterialTheme.colorScheme.secondary, modifier = Modifier.padding(top = 4.dp, bottom = 2.dp) ) } // --- Slot: Injected directly below the action buttons --- basicSectionBottom { Text( text = "Notes: Great quiet atmosphere for meetings.", style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant ) } } }
Configurazione avanzata di Place Details
Utilizza l'AdvancedPlaceDetailsFragment o l'AdvancedPlaceDetailsCompactFragment per accedere alle funzionalità avanzate.
Configura i pulsanti di azione
Utilizza l'interfaccia PlaceActionProvider di AdvancedPlaceDetailsFragment o AdvancedPlaceDetailsCompactFragment per definire e personalizzare i pulsanti di azione.
Se utilizzi le funzioni @composable, utilizza le lambda mainActions e cornerActions per configurare i pulsanti di azione.
Requisiti di attribuzione visiva
Importante: devi chiarire agli utenti finali quando un pulsante di azione personalizzata condividerà le informazioni utente con una terza parte diversa da Google. Consulta i requisiti di attribuzione visiva.
L'esempio a destra mostra un'immagine personalizzata che indica chiaramente che le informazioni dell'utente verranno inviate ad "Altostrat".
Applica le opzioni di ricerca e filtro
Utilizza le classi SearchMediaOptions e SearchReviewsOptions di AdvancedPlaceDetailsFragment o AdvancedPlaceDetailsCompactFragment per attivare la ricerca e l'applicazione di filtri per i contenuti multimediali o le recensioni.
Se utilizzi le funzioni @composable, utilizza com.google.android.libraries.places.compose.search.SearchMediaOptions per attivare la ricerca e il filtro di contenuti multimediali o recensioni.
Crea aree contenuti personalizzate
Gli slot per contenuti personalizzati ti consentono di aggiungere i tuoi contenuti (come riepiloghi generati dall'AI, timestamp degli itinerari o badge personalizzati) direttamente in zone di layout predefinite.
Requisiti di attribuzione e suggerimenti per gli slot di contenuti
Quando viene montato un area contenuti personalizzata, l'informativa si aggiorna automaticamente per chiarire quali contenuti sono forniti da Google e che alcuni contenuti sono forniti da terze parti.
Cosa fare
Mantieni una gerarchia visiva chiara tra i dettagli di Google Places e i contenuti personalizzati per evitare ambiguità sull'origine delle informazioni.
Cosa fare
Prendi in considerazione approfondimenti localizzati e di alto valore, personalizzati in base agli obiettivi immediati dei tuoi utenti. Contenuti personalizzati, come finestre di prenotazione in tempo reale o disponibilità attuale, aiutano gli utenti a prendere decisioni più rapide e informate.
Cosa non fare
Non duplicare i dettagli di Google Places esistenti, come valutazioni, recensioni o orari di apertura, anche se hai nascosto i contenuti forniti da Google. In questo modo, gli utenti potrebbero confondersi sull'origine dei contenuti e non capire se provengono da Google o da una terza parte.
Cosa non fare
Non mostrare affermazioni o badge non attribuiti (ad esempio, "Contenuto consigliato") che potrebbero essere scambiati per approvazioni ufficiali di Google. I contenuti personalizzati devono attribuire esplicitamente la propria fonte.
Cosa non fare
Non includere annunci, testi di marketing, sconti promozionali o richieste di abbonamento all'interno di contenitori di luoghi personalizzati.
Per aggiungere contenuti personalizzati, utilizza il componibile AdvancedPlaceDetailsCompact. Utilizza basicSectionTop o basicSectionBottom per specificare la posizione dei contenuti.
Esempi di Place Details (Advanced)
Personalizza i pulsanti di azione
Utilizza l'interfaccia PlaceActionProvider per controllare quali azioni sono disponibili per ogni luogo.
Kotlin
class PlaceDetailsWidgetTestActivity : BaseActivity() { // simplified example of starting the fragment fun setupPPDFragment() { fullWidgetSelectedContent = AdvancedPlaceDetailsFragment.ALL_CONTENT.toMutableList() AdvancedPlaceDetailsFragment.newInstance(fullWidgetSelectedContent, Orientation.VERTICAL) supportFragmentManager .beginTransaction() .replace(R.id.fragment_container, fragment!!) .commitNow() } // you can set the callback elsewhere, but this is the ideal callback spot override fun onAttachFragment(fragment: Fragment) { super.onAttachFragment(fragment) when (fragment) { is PlaceActionController -> setPlaceActionProvider(fragment) } } // have this callback return an empty list to hide all buttons // if this callback isn't set, default buttons appear private fun setPlaceActionProvider(fragment: PlaceActionController) { fragment.setPlaceActionProvider( object : PlaceActionProvider { override fun getMainPlaceActions(place: Place): List<PlaceAction> = buildList { // predefined actions can be mixed in with custom ones add(PlaceAction.OPEN_IN_MAPS) // example of button with both text label and icon add( PlaceAction.builder() .setLabelTextResId(R.string.custom_action) .setIconResId(R.drawable.gs_custom_action_icon) .setContentDescriptionResId(R.string.custom_action_description) .setOnClickListener { /* todo perform action */ } .build() ) // icon only button add( PlaceAction.builder() .setIconResId(R.drawable.custom_action_icon_2) .setContentDescriptionResId(R.string.custom_action_description_2) .setOnClickListener { /* todo perform action */} .build() ) // text label only button add( PlaceAction.builder() .setLabelTextResId(R.string.custom_action_3) .setContentDescriptionResId(R.string.custom_action_description_2) .setOnClickListener {/* todo perform action */ } .build() ) } /** You can also specify whether corner buttons should appear. For either callback, returning an empty list results in no buttons appearing */ override fun getCornerPlaceActions(place: Place): List<PlaceAction> { return emptyList() } override fun addPlaceActionsChangedListener( listener: PlaceActionProvider.OnChangedListener ) { // in this example, just one listener and widget this@HostAppActivity.listener = listener } override fun removePlaceActionsChangedListener( listener: PlaceActionProvider.OnChangedListener ) { // if there are multiple listeners, remove only the provided listener this@HostAppActivity.listener = null } }) } }
Aggiungi azioni personalizzate e predefinite
Questo esempio aggiunge un pulsante di attivazione/disattivazione che consente a un utente di aggiungere o rimuovere un luogo dai preferiti.
Kotlin
private var listener: PlaceActionProvider.OnChangedListener? = null private fun setPlaceActionProvider(fragment: PlaceActionController) { fragment.setPlaceActionProvider( object : PlaceActionProvider { private var placeFavorited = false override fun getMainPlaceActions(place: Place): List<PlaceAction> { val buttonList = mutableListOf<PlaceAction>() if (placeFavorited) { buttonList.add( PlaceAction.builder() .setLabelTextResId(R.string.place_details_button_config_favorite) .setIconResId(R.drawable.gs_web_vd_theme_24) .setOnClickListener { placeFavorited = !placeFavorited refreshButtonConfigs() } .build() ) } else { buttonList.add( PlaceAction.builder() .setLabelTextResId(R.string.place_details_button_config_unfavorite) .setIconResId(R.drawable.gs_web_vd_theme_24) .setOnClickListener { placeFavorited = !placeFavorited refreshButtonConfigs() } .build() ) } return buttonList } override fun addPlaceActionsChangedListener( listener: PlaceActionProvider.OnChangedListener ) { this@PlaceDetailsWidgetTestActivity.listener = listener } override fun removePlaceActionsChangedListener( listener: PlaceActionProvider.OnChangedListener ) { // if there are multiple listeners, remove only the provided listener this@PlaceDetailsWidgetTestActivity.listener = null } } ) } private fun refreshButtonConfigs() { listener?.onPlaceActionsChanged() }
Utilizza i pulsanti standard predefiniti
Crea pulsanti di azione che eseguono azioni standard definite da Google.
Kotlin
override fun getMainPlaceActions(place: Place): List<PlaceAction> { val buttonList = mutableListOf<PlaceAction>() // these buttons will have different background and text color than user-created buttons. // Text and icon button buttonList.add(PlaceAction.OPEN_IN_MAPS) // Icon-only buttons not enabled for main action buttons // Use of kotlin extension to do the same. see PlaceAction.OPEN_IN_MAPS { setIconResId(0) } return buttonList }
Filtra recensioni e contenuti multimediali
Questo esempio di codice mostra solo i contenuti multimediali e le recensioni che menzionano "spaghetti" e "gustoso".
Kotlin
import com.google.android.libraries.places.widget.AdvancedPlaceDetailsFragment import com.google.android.libraries.places.widget.model.SearchMediaOptions import com.google.android.libraries.places.widget.model.SearchReviewsOptions import com.google.android.libraries.places.widget.model.Orientation import com.google.android.libraries.places.R // 1. Create options using the Java builders (called from Kotlin) val mediaOptions = SearchMediaOptions.builder() .setQuery("spaghetti") .setRankPreference(SearchMediaOptions.RankPreference.MOST_RELEVANT) .build() val reviewOptions = SearchReviewsOptions.builder() .setQuery("tasty") .setRankPreference(SearchReviewsOptions.RankPreference.NEWEST) .build() // 2. Create the fragment val fragment = AdvancedPlaceDetailsFragment.newInstance( AdvancedPlaceDetailsFragment.STANDARD_CONTENT, Orientation.VERTICAL, R.style.PlacesMaterialTheme ) // 3. Apply options to the fragment fragment.applySearchMediaOptions(mediaOptions) fragment.applySearchReviewsOptions(reviewOptions)
Crea aree contenuti
Kotlin
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import com.google.android.libraries.places.compose.AdvancedPlaceDetailsCompact import com.google.android.libraries.places.compose.PlaceReference @Composable fun ItineraryPlaceCard(placeId: String) { AdvancedPlaceDetailsCompact( reference = PlaceReference.PlaceId(placeId) ) { // Slot: Injected directly above the place name basicSectionTop { Text( text = "Day 2 • 2:30 PM", style = MaterialTheme.typography.labelSmall, color = MaterialTheme.colorScheme.primary ) } // Slot: Injected directly below the main action buttons basicSectionBottom { NotesCard( notes = "Great quiet atmosphere for morning meetings. Famous for house-roasted pour-overs." ) } } }