با مجموعهها، منظم بمانید
ذخیره و طبقهبندی محتوا براساس اولویتهای شما.
List-detail یک الگوی رابط کاربری است که از یک طرح بندی دو صفحه ای تشکیل شده است که در آن یک صفحه فهرستی از آیتم ها را ارائه می دهد و صفحه دیگری جزئیات موارد انتخاب شده از لیست را نمایش می دهد.
این الگو به ویژه برای برنامههایی مفید است که اطلاعات عمیقی درباره عناصر مجموعههای بزرگ ارائه میدهند، به عنوان مثال، یک سرویس گیرنده ایمیل که فهرستی از ایمیلها و محتوای دقیق هر پیام ایمیل را دارد. فهرست جزئیات همچنین میتواند برای مسیرهای کمتر مهم مانند تقسیم اولویتهای برنامه به فهرستی از دستهها با اولویتهای هر دسته در قسمت جزئیات استفاده شود.
شکل 1. هنگامی که اندازه صفحه نمایش کافی در دسترس باشد، صفحه جزئیات در کنار صفحه فهرست نشان داده می شود. شکل 2. هنگامی که اندازه صفحه نمایش محدود است، صفحه جزئیات (از آنجایی که یک مورد انتخاب شده است) کل فضا را اشغال می کند.
الگوی List-Detail را با NavigableListDetailPaneScaffold پیاده سازی کنید
NavigableListDetailPaneScaffold یک قابلیت ترکیب است که اجرای طرح بندی جزئیات لیست را در Jetpack Compose ساده می کند. ListDetailPaneScaffold را میپیچد و ناوبری داخلی و انیمیشنهای پیشبینیکننده را اضافه میکند.
یک داربست با جزئیات لیست حداکثر از سه صفحه پشتیبانی می کند:
صفحه فهرست : مجموعه ای از موارد را نمایش می دهد.
صفحه جزئیات : جزئیات یک مورد انتخاب شده را نشان می دهد.
صفحه اضافی ( اختیاری ) : در صورت نیاز زمینه اضافی را فراهم می کند.
داربست بر اساس اندازه پنجره سازگار می شود:
در پنجره های بزرگ، لیست و پنجره های جزئیات در کنار هم ظاهر می شوند.
در پنجرههای کوچک، تنها یک صفحه در هر زمان قابل مشاهده است، که با حرکت کاربران تغییر میکند.
adaptive-layout: طرحبندیهای تطبیقی مانند ListDetailPaneScaffold و SupportingPaneScaffold
adaptive-navigation: قابلیت های Composable برای پیمایش درون و بین پنجره ها و همچنین طرح بندی های تطبیقی که به طور پیش فرض از ناوبری پشتیبانی می کنند مانند NavigableListDetailPaneScaffold و NavigableSupportingPaneScaffold
برای فعال کردن انیمیشنهای پیشبینیکننده پیشبینی در Android 15 یا پایینتر، باید برای پشتیبانی از حرکت پیشبینیکننده برگشت شرکت کنید. برای شرکت کردن، android:enableOnBackInvokedCallback="true" را به تگ <application> یا تگ های <activity> فردی در فایل AndroidManifest.xml خود اضافه کنید. برای اطلاعات بیشتر، شرکت در حرکت پیشگویانه برگشت را ببینید.
هنگامی که برنامه شما Android 16 (سطح API 36) یا بالاتر را هدف قرار داد، پیشبینی بازگشت به طور پیشفرض فعال میشود.
استفاده اساسی
NavigableListDetailPaneScaffold به صورت زیر پیاده سازی کنید:
از کلاسی استفاده کنید که محتوای انتخاب شده را نشان دهد. از یک کلاس Parcelable برای پشتیبانی از ذخیره و بازیابی آیتم لیست انتخاب شده استفاده کنید. از افزونه kotlin-parcelize برای تولید کد برای شما استفاده کنید.
با rememberListDetailPaneScaffoldNavigator یک ThreePaneScaffoldNavigator ایجاد کنید.
این ناوبر برای جابجایی بین لیست، جزئیات و پنجره های اضافی استفاده می شود. با اعلام یک نوع عمومی، ناوبر وضعیت داربست (یعنی MyItem در حال نمایش) را نیز ردیابی می کند. از آنجایی که این نوع قابل تقسیم است، وضعیت می تواند توسط ناوبر ذخیره و بازیابی شود تا به طور خودکار تغییرات پیکربندی را مدیریت کند.
ناوبر را به NavigableListDetailPaneScaffold قابل ترکیب منتقل کنید.
پیاده سازی پنجره لیست خود را به NavigableListDetailPaneScaffold عرضه کنید. از AnimatedPane برای اعمال انیمیشن های صفحه پیش فرض در حین پیمایش استفاده کنید. سپس از ThreePaneScaffoldNavigator برای رفتن به قسمت جزئیات، ListDetailPaneScaffoldRole.Detail و نمایش آیتم ارسال شده استفاده کنید.
پیاده سازی پنجره جزئیات خود را در NavigableListDetailPaneScaffold قرار دهید.
هنگامی که پیمایش کامل شد، currentDestination شامل قسمتی است که برنامه شما به آن پیمایش کرده است، از جمله محتوای نمایش داده شده در کادر. ویژگی contentKey همان نوع مشخص شده در تماس اصلی است، بنابراین شما می توانید به هر داده ای که برای نمایش نیاز دارید دسترسی داشته باشید.
به صورت اختیاری، defaultBackBehavior در NavigableListDetailPaneScaffold تغییر دهید. به طور پیشفرض، NavigableListDetailPaneScaffold از PopUntilScaffoldValueChange برای defaultBackBehavior استفاده میکند.
اگر برنامه شما به الگوی پیمایش برگشتی متفاوتی نیاز دارد، میتوانید با مشخص کردن گزینه BackNavigationBehavior دیگری، این رفتار را لغو کنید.
گزینه های BackNavigationBehavior
بخش زیر از مثال یک برنامه ایمیل با لیستی از ایمیل ها در یک بخش و نمای دقیق در قسمت دیگر استفاده می کند.
PopUntilScaffoldValueChange (پیشفرض و در بیشتر موارد توصیه میشود)
این رفتار بر تغییرات ساختار طرح کلی تمرکز دارد. در تنظیمات چند صفحه ای، تغییر محتوای ایمیل در قسمت جزئیات، ساختار طرح بندی زیرین را تغییر نمی دهد. بنابراین، دکمه بازگشت ممکن است از برنامه یا نمودار ناوبری فعلی خارج شود زیرا هیچ تغییری در طرح بندی برای بازگشت به آن در زمینه فعلی وجود ندارد. در طرحبندی تکپنجرهای، با فشار دادن به عقب، از تغییرات محتوا در نمای جزئیات عبور میکنید و به نمای فهرست بازمیگردید، زیرا این نشاندهنده تغییر طرحبندی واضح است.
به مثال های زیر توجه کنید:
Multi-Pane: شما در حال مشاهده یک ایمیل (مورد 1) در قسمت جزئیات هستید. با کلیک بر روی ایمیل دیگر (مورد 2) صفحه جزئیات به روز می شود، اما لیست و پنجره های جزئیات قابل مشاهده هستند. فشار دادن به عقب ممکن است از برنامه یا جریان ناوبری فعلی خارج شود.
Single-Pane: شما آیتم 1 و سپس آیتم 2 را مشاهده می کنید، با فشار دادن به عقب مستقیماً به صفحه لیست ایمیل باز می گردید.
هنگامی که می خواهید کاربران با هر عمل برگشتی، تغییرات طرح بندی متمایز را درک کنند، از این استفاده کنید.
PopUntilContentChange
این رفتار محتوای نمایش داده شده را در اولویت قرار می دهد. اگر آیتم 1 و سپس آیتم 2 را مشاهده کنید، بدون در نظر گرفتن طرح بندی، با فشردن بازگشت به آیتم 1 باز می گردد.
به مثال های زیر توجه کنید:
Multi-Pane: مورد 1 را در قسمت جزئیات مشاهده می کنید، سپس روی مورد 2 در لیست کلیک کنید. صفحه جزئیات به روز می شود. با فشار دادن به عقب، صفحه جزئیات به آیتم 1 باز می گردد.
Single-Pane: همان بازگشت محتوا رخ می دهد.
زمانی که کاربر انتظار دارد با اکشن برگشتی به محتوایی که قبلاً مشاهده کرده است، از این استفاده کنید.
PopUntilCurrentDestinationChange
این رفتار پشته پشتی را باز می کند تا زمانی که مقصد ناوبری فعلی تغییر کند. این به طور یکسان برای طرحبندیهای تک و چند صفحهای صدق میکند.
به مثال های زیر توجه کنید:
صرف نظر از اینکه در یک طرح بندی تک یا چند صفحه ای هستید، با فشار دادن به عقب، فوکوس همیشه از عنصر پیمایش برجسته شده به مقصد قبلی منتقل می شود. در برنامه ایمیل ما، این بدان معنی است که نشانه بصری صفحه انتخاب شده تغییر خواهد کرد.
هنگامی که حفظ یک نشانه بصری واضح از ناوبری فعلی برای تجربه کاربر بسیار مهم است، از این استفاده کنید.
PopLatest
این گزینه فقط آخرین مقصد را از پشت پشتی حذف می کند. از این گزینه برای پیمایش به عقب بدون پرش از حالت های میانی استفاده کنید.
پس از اجرای این مراحل، کد شما باید شبیه به شکل زیر باشد:
valscaffoldNavigator=rememberListDetailPaneScaffoldNavigator<MyItem>()valscope=rememberCoroutineScope()NavigableListDetailPaneScaffold(navigator=scaffoldNavigator,listPane={AnimatedPane{MyList(onItemClick={item->
// Navigate to the detail pane with the passed itemscope.launch{scaffoldNavigator.navigateTo(ListDetailPaneScaffoldRole.Detail,item)}},)}},detailPane={AnimatedPane{// Show the detail pane content if selected item is availablescaffoldNavigator.currentDestination?.contentKey?.let{MyDetails(it)}}},)
محتوا و نمونه کدها در این صفحه مشمول پروانههای توصیفشده در پروانه محتوا هستند. جاوا و OpenJDK علامتهای تجاری یا علامتهای تجاری ثبتشده Oracle و/یا وابستههای آن هستند.
تاریخ آخرین بهروزرسانی 2025-08-28 بهوقت ساعت هماهنگ جهانی.
[[["درک آسان","easyToUnderstand","thumb-up"],["مشکلم را برطرف کرد","solvedMyProblem","thumb-up"],["غیره","otherUp","thumb-up"]],[["اطلاعاتی که نیاز دارم وجود ندارد","missingTheInformationINeed","thumb-down"],["بیشازحد پیچیده/ مراحل بسیار زیاد","tooComplicatedTooManySteps","thumb-down"],["قدیمی","outOfDate","thumb-down"],["مشکل ترجمه","translationIssue","thumb-down"],["مشکل کد / نمونهها","samplesCodeIssue","thumb-down"],["غیره","otherDown","thumb-down"]],["تاریخ آخرین بهروزرسانی 2025-08-28 بهوقت ساعت هماهنگ جهانی."],[],[],null,["List-detail is a UI pattern that consists of a dual-pane layout where one pane\npresents a list of items and another pane displays the details of items selected\nfrom the list.\n\nThe pattern is particularly useful for applications that provide in-depth\ninformation about elements of large collections, for example, an email client\nthat has a list of emails and the detailed content of each email message.\nList-detail can also be used for less critical paths such as dividing app\npreferences into a list of categories with the preferences for each category in\nthe detail pane.\n**Figure 1.** When enough screen size is available, the detail pane is shown alongside the list pane. **Figure 2.** When screen size is limited, the detail pane (since an item has been selected) takes over the whole space.\n\nImplement the List-Detail Pattern with `NavigableListDetailPaneScaffold`\n\n`NavigableListDetailPaneScaffold` is a composable that simplifies implementing a\nlist-detail layout in Jetpack Compose. It wraps `ListDetailPaneScaffold` and\nadds built-in navigation and predictive back animations.\n\nA list-detail scaffold supports up to three panes:\n\n1. **List pane**: Displays a collection of items.\n2. **Detail pane**: Shows the details of a selected item.\n3. **Extra pane (*optional*)**: Provides additional context when needed.\n\nThe scaffold adapts based on window size:\n\n- In large windows, the list and detail panes appear side by side.\n- In small windows, only one pane is visible at a time, switching as users navigate.\n\nDeclare dependencies\n\n`NavigableListDetailPaneScaffold` is part of the [Material 3 adaptive navigation\nlibrary](/reference/kotlin/androidx/compose/material3/adaptive/layout/package-summary).\n\nAdd the following three related dependencies to the `build.gradle` file of your\napp or module: \n\nKotlin \n\n```kotlin\nimplementation(\"androidx.compose.material3.adaptive:adaptive\")\nimplementation(\"androidx.compose.material3.adaptive:adaptive-layout\")\nimplementation(\"androidx.compose.material3.adaptive:adaptive-navigation\")\n```\n\nGroovy \n\n```groovy\nimplementation 'androidx.compose.material3.adaptive:adaptive'\nimplementation 'androidx.compose.material3.adaptive:adaptive-layout'\nimplementation 'androidx.compose.material3.adaptive:adaptive-navigation'\n```\n\n- adaptive: Low-level building blocks such as [`HingeInfo`](/reference/kotlin/androidx/compose/material3/adaptive/HingeInfo) and [`Posture`](/reference/kotlin/androidx/compose/material3/adaptive/Posture)\n- adaptive-layout: Adaptive layouts such as `ListDetailPaneScaffold` and [`SupportingPaneScaffold`](/reference/kotlin/androidx/compose/material3/adaptive/layout/package-summary#SupportingPaneScaffold(androidx.compose.material3.adaptive.layout.PaneScaffoldDirective,androidx.compose.material3.adaptive.layout.ThreePaneScaffoldValue,kotlin.Function1,kotlin.Function1,androidx.compose.ui.Modifier,kotlin.Function1))\n- adaptive-navigation: Composables for navigating within and between panes, as well as adaptive layouts that support navigation by default such as `NavigableListDetailPaneScaffold` and `NavigableSupportingPaneScaffold`\n\nEnsure your project includes [compose-material3-adaptive version 1.1.0-beta1](/jetpack/androidx/releases/compose-material3-adaptive#1.1.0-beta01)\nor higher.\n\nOpt-in to the predictive back gesture\n\nTo enable predictive back animations in Android 15 or lower, you must opt-in\nto support the predictive back gesture. To opt-in, add\n`android:enableOnBackInvokedCallback=\"true\"` to the `\u003capplication\u003e` tag or\nindividual `\u003cactivity\u003e` tags within your `AndroidManifest.xml` file. For more\ninformation, see [Opt-in to the predictive back gesture](/guide/navigation/custom-back/predictive-back-gesture#opt-predictive).\n\nOnce your app targets Android 16 (API level 36) or higher, predictive back is\nenabled by default.\n\nBasic usage\n\nImplement `NavigableListDetailPaneScaffold` as follows:\n\n1. Use a class that represents the selected content. Use a [`Parcelable`](/reference/android/os/Parcelable) class to support saving and restoring the selected list item. Use the [kotlin-parcelize plugin](/kotlin/parcelize) to generate the code for you.\n2. Create a `ThreePaneScaffoldNavigator` with `rememberListDetailPaneScaffoldNavigator`.\n\nThis navigator is used to move between the list, detail, and extra panes. By\ndeclaring a generic type, the navigator also tracks the state of the scaffold\n(that is, which `MyItem` is being displayed). Since this type is parcelable, the\nstate can be saved and restored by the navigator to automatically handle\nconfiguration changes.\n\n1. Pass the navigator to the `NavigableListDetailPaneScaffold` composable.\n\n2. Supply your list pane implementation to the\n `NavigableListDetailPaneScaffold`. Use [`AnimatedPane`](/reference/kotlin/androidx/compose/material3/adaptive/layout/ThreePaneScaffoldScope#(androidx.compose.material3.adaptive.layout.ThreePaneScaffoldScope).AnimatedPane(androidx.compose.ui.Modifier,kotlin.Function1)) to apply the\n default pane animations during navigation. Then use `ThreePaneScaffoldNavigator`\n to navigate to the detail pane, `ListDetailPaneScaffoldRole.Detail`, and display\n the passed item.\n\n3. Include your detail pane implementation in `NavigableListDetailPaneScaffold`.\n\nWhen navigation is complete, `currentDestination` contains the pane your app\nhas navigated to, including the content displayed in the pane. The `contentKey`\nproperty is the same type specified in the original call so you can access\nany data that you need to display.\n\n1. Optionally, change the `defaultBackBehavior` in `NavigableListDetailPaneScaffold`. By default, `NavigableListDetailPaneScaffold` uses `PopUntilScaffoldValueChange` for `defaultBackBehavior`.\n\nIf your app requires a different back navigation pattern, you can override this\nbehavior by specifying another `BackNavigationBehavior` option.\n\n`BackNavigationBehavior` options\n\nThe following section uses the example of an email app with a list of emails in\none pane and a detailed view in the other.\n\n`PopUntilScaffoldValueChange` (Default and recommended in most cases)\n\nThis behavior focuses on changes to the overall layout structure. In a\nmulti-pane setup, changing the email content in the detailed pane doesn't alter\nthe underlying layout structure. Therefore, the back button might exit the app\nor the current navigation graph because there's no layout change to revert to\nwithin the current context. In a single-pane layout, pressing back will skip\nthrough content changes within the detail view and return to the list view, as\nthis represents a clear layout change.\n\nConsider the following examples:\n\n- **Multi-Pane:** You're viewing an email (Item 1) in the detail pane. Clicking on another email (Item 2) updates the detail pane, but the list and detail panes remain visible. Pressing back might exit the app or the current navigation flow.\n- **Single-Pane:** You view Item 1, then Item 2, pressing back will return you directly to the email list pane.\n\nUse this when you want users to perceive distinct layout transitions with each\nback action.\n\n`PopUntilContentChange`\n\nThis behavior prioritizes the content displayed. If you view Item 1 and then\nItem 2, pressing back will revert to Item 1, regardless of the layout.\n\nConsider the following examples:\n\n- **Multi-Pane:** You view Item 1 in the detail pane, then click Item 2 in the list. The detail pane updates. Pressing back will restore the detail pane to Item 1.\n- **Single-Pane:** The same content reversion occurs.\n\nUse this when your user expects to return to the previously viewed content with\nthe back action.\n\n`PopUntilCurrentDestinationChange`\n\nThis behavior pops the back stack until the *current navigation destination*\nchanges. This applies equally to single and multi-pane layouts.\n\nConsider the following examples:\n\nRegardless of whether you're in a single or multi-pane layout, pressing back\nwill always move the focus from the highlighted navigation element to the\nprevious destination. In our email app, this means the visual indication of\nthe selected pane will shift.\n\nUse this when maintaining a clear visual indication of the current navigation\nis crucial for the user experience.\n\n`PopLatest`\n\nThis option removes only the most recent destination from the backstack. Use\nthis option for back navigation without skipping intermediate states.\n| **Note:** Multi-pane layouts may create navigation backstacks that are not possible in single-pane layouts, such as navigating directly from one detail item to another. If the device size changes mid-navigation, this behavior may produce unintuitive results.\n\nAfter you implement these steps, your code should look similar to the following:\n\n\n```kotlin\nval scaffoldNavigator = rememberListDetailPaneScaffoldNavigator\u003cMyItem\u003e()\nval scope = rememberCoroutineScope()\n\nNavigableListDetailPaneScaffold(\n navigator = scaffoldNavigator,\n listPane = {\n AnimatedPane {\n MyList(\n onItemClick = { item -\u003e\n // Navigate to the detail pane with the passed item\n scope.launch {\n scaffoldNavigator.navigateTo(\n ListDetailPaneScaffoldRole.Detail,\n item\n )\n }\n },\n )\n }\n },\n detailPane = {\n AnimatedPane {\n // Show the detail pane content if selected item is available\n scaffoldNavigator.currentDestination?.contentKey?.let {\n MyDetails(it)\n }\n }\n },\n)https://github.com/android/snippets/blob/dd30aee903e8c247786c064faab1a9ca8d10b46e/compose/snippets/src/main/java/com/example/compose/snippets/adaptivelayouts/SampleListDetailPaneScaffold.kt#L119-L147\n```\n\n\u003cbr /\u003e"]]