کامپوننت جزئیات مکان پیشرفته
نسخه پیشرفته کامپوننت Place Details همان ویژگیهای Places Details Essentials را ارائه میدهد. همچنین به شما امکان میدهد دکمههای عملیاتی کامپوننت را پیکربندی کنید و گزینههای جستجو و فیلتر را برای نظرات و رسانههای نمایش داده شده اعمال کنید.
پشتیبانی داخلی از Jetpack Compose
کیت رابط کاربری Places توابع @Composable مربوط به Jetpack Compose را برای AdvancedPlaceDetailsCompact ارائه میدهد. این composableها از حالت hoisted، پشتیبانی از اصلاحکنندههای داخلی و اسلاتهای DSL بومی Compose استفاده میکنند.
نمونه کد زیر نحوه استفاده از تابع composable را برای طرحبندی عمودی نشان میدهد.
کاتلین
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 ) } } }
پیکربندی پیشرفته جزئیات مکان
برای دسترسی به ویژگیهای پیشرفته، از AdvancedPlaceDetailsFragment یا AdvancedPlaceDetailsCompactFragment استفاده کنید.
پیکربندی دکمههای عملیاتی
برای تعریف و سفارشیسازی دکمههای عملیاتی، از رابط PlaceActionProvider مربوط به AdvancedPlaceDetailsFragment یا AdvancedPlaceDetailsCompactFragment استفاده کنید.
اگر از توابع @composable استفاده میکنید، از لامبداهای mainActions و cornerActions برای پیکربندی دکمههای عملیاتی استفاده کنید.
الزامات انتساب بصری
مهم: شما باید برای کاربران نهایی روشن کنید که چه زمانی یک دکمه اقدام سفارشی، اطلاعات کاربر را با شخص ثالثی غیر از گوگل به اشتراک میگذارد. به الزامات انتساب بصری مراجعه کنید.
مثال سمت راست یک تصویر سفارشی را نشان میدهد که به وضوح نشان میدهد اطلاعات کاربر به «Altostrat» ارسال خواهد شد.
اعمال گزینههای جستجو و فیلتر
از کلاسهای SearchMediaOptions و SearchReviewsOptions از AdvancedPlaceDetailsFragment یا AdvancedPlaceDetailsCompactFragment برای فعال کردن جستجو و فیلتر کردن رسانهها یا نظرات استفاده کنید.
اگر از توابع @composable استفاده میکنید، از com.google.android.libraries.places.compose.search.SearchMediaOptions برای فعال کردن جستجو و فیلتر کردن رسانهها یا نظرات استفاده کنید.
ایجاد اسلاتهای محتوای سفارشی

اسلاتهای محتوای سفارشی به شما امکان میدهند محتوای خود (مانند خلاصههای تولید شده توسط هوش مصنوعی، مهرهای زمانی برنامه سفر یا نشانهای سفارشی) را مستقیماً به مناطق طرحبندی از پیش تعریف شده اضافه کنید.
الزامات انتساب و پیشنهادهای محتوا برای بخشهای محتوایی
وقتی یک جایگاه محتوای سفارشی ایجاد میشود، این افشا بهطور خودکار بهروزرسانی میشود تا مشخص شود کدام محتوا توسط گوگل ارائه شده و برخی محتوا توسط اشخاص ثالث ارائه شده است.
انجام دهید
برای جلوگیری از هرگونه ابهام در مورد منبع اطلاعات، سلسله مراتب بصری واضحی را بین جزئیات Google Place و محتوای سفارشی حفظ کنید.

انجام دهید
بینشهای محلی و ارزشمند متناسب با اهداف فوری کاربران خود را در نظر بگیرید. محتوای متناسب مانند پنجرههای رزرو در لحظه یا موجودی فعلی به کاربران کمک میکند تا تصمیمات سریعتر و آگاهانهتری بگیرند.

نکن
حتی اگر محتوای ارائه شده توسط گوگل را پنهان کردهاید، جزئیات موجود در گوگل پلیس، مانند رتبهبندیها، نظرات یا ساعات کاری را کپی نکنید. انجام این کار میتواند کاربران را در مورد منبع محتوا و اینکه آیا از گوگل یا شخص ثالث است، گیج کند.

نکن
ادعاها یا نشانهای بدون منبع (مثلاً «توصیه برتر!») را که ممکن است با تأییدیههای رسمی گوگل اشتباه گرفته شوند، نمایش ندهید. محتوای سفارشی باید صریحاً منبع خود را ذکر کند.

نکن
تبلیغات، متن بازاریابی، تخفیفهای تبلیغاتی یا درخواستهای اشتراک را در جعبههای سفارشی قرار ندهید.

برای افزودن محتوای سفارشی، از ترکیببندی AdvancedPlaceDetailsCompact استفاده کنید. برای مشخص کردن موقعیت محتوا basicSectionTop یا basicSectionBottom استفاده کنید.
مثالهای جزئیات مکان پیشرفته
سفارشیسازی دکمههای عملیاتی
از رابط PlaceActionProvider برای کنترل اینکه کدام اقدامات برای هر مکان در دسترس است، استفاده کنید.
کاتلین
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 } }) } }
افزودن اقدامات سفارشی و از پیش تعریف شده
این نمونه یک دکمهی تغییر وضعیت برای کاربر اضافه میکند تا بتواند یک مکان را به لیست علاقهمندیها اضافه کند یا از لیست علاقهمندیها حذف کند.
کاتلین
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() }
استفاده از دکمههای استاندارد از پیش تعریف شده
دکمههای عملیاتی ایجاد کنید که اقدامات استاندارد تعریفشده توسط گوگل را انجام دهند.
کاتلین
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 }
فیلتر کردن نظرات و رسانهها
این نمونه کد فقط رسانهها و نظراتی را نشان میدهد که به «اسپاگتی» و «خوشمزه» اشاره کردهاند.
کاتلین
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)
ایجاد اسلاتهای محتوا
کاتلین
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." ) } } }