Оптимизируйте свои подборки
Сохраняйте и классифицируйте контент в соответствии со своими настройками.
List-detail — это шаблон пользовательского интерфейса, состоящий из двухпанельной компоновки, где одна панель отображает список элементов, а другая — подробную информацию об элементах, выбранных из списка.
Этот шаблон особенно полезен для приложений, предоставляющих подробную информацию об элементах больших коллекций, например, для почтового клиента, хранящего список адресов электронной почты и подробное содержание каждого сообщения. List-detail также можно использовать для менее критичных задач, например, для разделения настроек приложения на список категорий с отображением настроек для каждой категории в области подробностей.
Рисунок 1. При достаточном размере экрана панель сведений отображается рядом с панелью списка. Рисунок 2. Если размер экрана ограничен, панель сведений (после выбора элемента) занимает все пространство.
Реализуйте шаблон «Список-Подробности» с помощью NavigableListDetailPaneScaffold
NavigableListDetailPaneScaffold — это компонуемый объект, упрощающий реализацию макета со списком и деталями в Jetpack Compose. Он является оболочкой ListDetailPaneScaffold и добавляет встроенную навигацию и предиктивную анимацию возврата.
Шаблон списка-детали поддерживает до трех панелей:
Панель списка : отображает коллекцию элементов.
Панель сведений : отображает сведения о выбранном элементе.
Дополнительная панель ( необязательно ) : при необходимости предоставляет дополнительный контекст.
Леса адаптируются в зависимости от размера окна:
В больших окнах панели списка и сведений отображаются рядом.
В небольших окнах одновременно видна только одна панель, которая переключается по мере перемещения пользователя.
адаптивный: низкоуровневые строительные блоки, такие как HingeInfo и Posture
adaptive-layout: адаптивные макеты, такие как ListDetailPaneScaffold и SupportingPaneScaffold
адаптивная навигация: компонуемые элементы для навигации внутри панелей и между ними, а также адаптивные макеты, которые поддерживают навигацию по умолчанию, такие как NavigableListDetailPaneScaffold и NavigableSupportingPaneScaffold
Чтобы включить предиктивную анимацию «Назад» в Android 15 или более ранней версии, необходимо включить поддержку предиктивного жеста «Назад». Для этого добавьте android:enableOnBackInvokedCallback="true" к тегу <application> или отдельным тегам <activity> в файле AndroidManifest.xml . Подробнее см. в разделе «Подключение предиктивного жеста «Назад» .
Как только ваше приложение перейдет на Android 16 (уровень API 36) или выше, функция предиктивного возврата будет включена по умолчанию.
Базовое использование
Реализуйте NavigableListDetailPaneScaffold следующим образом:
Используйте класс, представляющий выбранный контент. Используйте класс Parcelable для поддержки сохранения и восстановления выбранного элемента списка. Используйте плагин kotlin-parcelize для генерации кода.
Создайте ThreePaneScaffoldNavigator с rememberListDetailPaneScaffoldNavigator .
Этот навигатор используется для перемещения между панелями списка, подробностей и дополнительных элементов. Объявляя универсальный тип, навигатор также отслеживает состояние скаффолда (то есть, какой MyItem отображается). Поскольку этот тип является парцелляционным, навигатор может сохранять и восстанавливать состояние для автоматической обработки изменений конфигурации.
Передайте навигатор в составной элемент NavigableListDetailPaneScaffold .
Предоставьте реализацию панели списка в NavigableListDetailPaneScaffold . Используйте AnimatedPane для применения анимации панели по умолчанию во время навигации. Затем используйте ThreePaneScaffoldNavigator для перехода к панели сведений ListDetailPaneScaffoldRole.Detail и отображения переданного элемента.
Включите реализацию вашей панели сведений в NavigableListDetailPaneScaffold .
После завершения навигации currentDestination содержит панель, на которую перешло ваше приложение, включая отображаемое на ней содержимое. Свойство contentKey имеет тот же тип, что и указанный в исходном вызове, поэтому вы можете получить доступ к любым данным, которые необходимо отобразить.
При желании можно изменить defaultBackBehavior в NavigableListDetailPaneScaffold . По умолчанию NavigableListDetailPaneScaffold использует PopUntilScaffoldValueChange для defaultBackBehavior .
Если вашему приложению требуется другой шаблон обратной навигации, вы можете переопределить это поведение, указав другой параметр BackNavigationBehavior .
BackNavigationBehavior поведения
В следующем разделе используется пример приложения электронной почты со списком писем на одной панели и подробным представлением на другой.
PopUntilScaffoldValueChange (по умолчанию и рекомендуется в большинстве случаев)
Это поведение фокусируется на изменениях общей структуры макета. В многопанельной конфигурации изменение содержимого письма в подробной панели не влияет на базовую структуру макета. Поэтому кнопка «Назад» может привести к выходу из приложения или текущего навигационного графика, поскольку в текущем контексте нет изменений макета, к которым можно вернуться. В однопанельной конфигурации нажатие кнопки «Назад» пропустит изменения содержимого в подробном представлении и вернёт в список, поскольку это представляет собой явное изменение макета.
Рассмотрим следующие примеры:
Многопанельное отображение: вы просматриваете электронное письмо (Элемент 1) на панели сведений. Нажатие на другое электронное письмо (Элемент 2) обновляет панель сведений, но список и панели сведений остаются видимыми. Нажатие кнопки «Назад» может привести к выходу из приложения или из текущего навигационного потока.
Однопанельная: вы просматриваете элемент 1, затем элемент 2, нажатие кнопки «Назад» вернет вас непосредственно на панель списка адресов электронной почты.
Используйте этот метод, когда вы хотите, чтобы пользователи воспринимали отдельные переходы макета при каждом возврате.
PopUntilContentChange
Такое поведение отдаёт приоритет отображаемому контенту. Если вы просматриваете элемент 1, а затем элемент 2, нажатие кнопки «Назад» вернёт вас к элементу 1, независимо от макета.
Рассмотрим следующие примеры:
Многопанельное отображение: сначала вы видите элемент 1 на панели сведений, затем нажимаете элемент 2 в списке. Панель сведений обновляется. Нажатие кнопки «Назад» вернет панель сведений к элементу 1.
Однопанельный режим: происходит тот же возврат содержимого.
Используйте этот вариант, когда пользователь ожидает вернуться к ранее просмотренному контенту с помощью действия «Назад».
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)}}},)
Контент и образцы кода на этой странице предоставлены по лицензиям. Java и OpenJDK – это зарегистрированные товарные знаки корпорации Oracle и ее аффилированных лиц.
Последнее обновление: 2025-08-28 UTC.
[null,null,["Последнее обновление: 2025-08-28 UTC."],[],[],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"]]