List-detail — это шаблон пользовательского интерфейса, который состоит из макета с двумя панелями, где одна панель представляет список элементов, а другая панель отображает сведения об элементах, выбранных из списка.
Этот шаблон особенно полезен для приложений, которые предоставляют подробную информацию об элементах больших коллекций, например, для почтового клиента, который имеет список электронных писем и подробное содержимое каждого сообщения электронной почты. List-detail также можно использовать для менее важных путей, таких как разделение настроек приложения на список категорий с настройками для каждой категории на панели сведений.
Реализуйте шаблон пользовательского интерфейса с помощью ListDetailPaneScaffold
ListDetailPaneScaffold
— это составной компонент, который упрощает реализацию шаблона подробностей списка в вашем приложении. Структура подробного списка может состоять из трех панелей: панели списка, панели подробностей и дополнительной панели. Эшаффолд выполняет расчеты экранного пространства. Если доступен достаточный размер экрана, панель сведений отображается рядом с панелью списка. На экранах небольших размеров scaffold автоматически переключается на полноэкранное отображение либо списка, либо панели подробностей.
![Панель сведений, отображаемая рядом со страницей списка.](https://developer.android.com/static/develop/ui/compose/images/layouts/adaptive/list-detail-2.png?authuser=2&hl=ru)
![После выбора элемента панель сведений занимает весь экран.](https://developer.android.com/static/develop/ui/compose/images/layouts/adaptive/list-detail-1.png?authuser=2&hl=ru)
Объявить зависимости
ListDetailPaneScaffold
— часть библиотеки адаптивной компоновки Material 3 .
Добавьте следующие три связанные зависимости в файл build.gradle
вашего приложения или модуля:
Котлин
implementation("androidx.compose.material3.adaptive:adaptive") implementation("androidx.compose.material3.adaptive:adaptive-layout") implementation("androidx.compose.material3.adaptive:adaptive-navigation")
классный
implementation 'androidx.compose.material3.adaptive:adaptive' implementation 'androidx.compose.material3.adaptive:adaptive-layout' implementation 'androidx.compose.material3.adaptive:adaptive-navigation'
- адаптивный — низкоуровневые строительные блоки, такие как
HingeInfo
иPosture
- Adaptive-layout — Адаптивные макеты, такие как
ListDetailPaneScaffold
иSupportingPaneScaffold
- Adaptive-navigation — Составные элементы для навигации внутри и между панелями
Основное использование
Реализуйте ListDetailPaneScaffold
следующим образом:
Используйте класс, представляющий выбираемое содержимое. Этот класс должен быть
Parcelable
чтобы поддерживать сохранение и восстановление выбранного элемента списка. Используйте плагин kotlin-parcelize для генерации кода.@Parcelize class MyItem(val id: Int) : Parcelable
Создайте
ThreePaneScaffoldNavigator
с помощьюrememberListDetailPaneScaffoldNavigator
и добавьтеBackHandler
. Этот навигатор используется для перемещения между списком, деталями и дополнительными панелями. Объявляя универсальный тип, навигатор также отслеживает состояние scaffold (то есть, какойMyItem
отображается). Поскольку этот тип можно разделить, состояние может быть сохранено и восстановлено навигатором для автоматической обработки изменений конфигурации.BackHandler
обеспечивает поддержку перехода назад с помощью системного жеста или кнопки. Ожидаемое поведение кнопки «Назад» дляListDetailPaneScaffold
зависит от размера окна и текущего значения шаблона. ЕслиListDetailPaneScaffold
поддерживает возврат к текущему состоянию, тогдаcanNavigateBack()
имеет значениеtrue
, что позволяетBackHandler
.val navigator = rememberListDetailPaneScaffoldNavigator<MyItem>() BackHandler(navigator.canNavigateBack()) { navigator.navigateBack() }
Передайте
scaffoldState
изnavigator
в составной элементListDetailPaneScaffold
.ListDetailPaneScaffold( directive = navigator.scaffoldDirective, value = navigator.scaffoldValue, // ... )
Предоставьте реализацию панели списка в
ListDetailPaneScaffold
. ИспользуйтеAnimatedPane
, чтобы применить анимацию панели по умолчанию во время навигации. Затем используйтеThreePaneScaffoldNavigator
, чтобы перейти к панели сведенийListDetailPaneScaffoldRole.Detail
и отобразить переданный элемент.ListDetailPaneScaffold( directive = navigator.scaffoldDirective, value = navigator.scaffoldValue, listPane = { AnimatedPane { MyList( onItemClick = { item -> // Navigate to the detail pane with the passed item navigator.navigateTo(ListDetailPaneScaffoldRole.Detail, item) } ) } }, // ... )
Включите реализацию области подробностей в
ListDetailPaneScaffold
. После завершения навигацииcurrentDestination
содержит панель, к которой перешло ваше приложение, включая содержимое, отображаемое на панели. Свойствоcontent
имеет тот же тип, что указан в исходном вызове запоминания (MyItem
в этом примере), поэтому вы также можете получить доступ к свойству для любых данных, которые вам нужно отобразить.ListDetailPaneScaffold( directive = navigator.scaffoldDirective, value = navigator.scaffoldValue, listPane = // ... detailPane = { AnimatedPane { navigator.currentDestination?.content?.let { MyDetails(it) } } }, )
После реализации описанных выше шагов ваш код должен выглядеть примерно так:
val navigator = rememberListDetailPaneScaffoldNavigator<MyItem>() BackHandler(navigator.canNavigateBack()) { navigator.navigateBack() } ListDetailPaneScaffold( directive = navigator.scaffoldDirective, value = navigator.scaffoldValue, listPane = { AnimatedPane { MyList( onItemClick = { item -> // Navigate to the detail pane with the passed item navigator.navigateTo(ListDetailPaneScaffoldRole.Detail, item) }, ) } }, detailPane = { AnimatedPane { // Show the detail pane content if selected item is available navigator.currentDestination?.content?.let { MyDetails(it) } } }, )