Макет вспомогательных панелей позволяет пользователю сосредоточиться на основном контенте приложения, одновременно отображая важную дополнительную информацию. Например, на главной панели может отображаться информация о фильме, а на вспомогательной — список похожих фильмов, фильмов того же режиссёра или работ с теми же актёрами.
Более подробную информацию см. в руководстве по вспомогательным панелям Material 3 .
Реализуйте опорную панель с помощью подмостей
NavigableSupportingPaneScaffold
— это компонуемый объект, упрощающий реализацию макета поддерживающих панелей в Jetpack Compose. Он является оболочкой SupportingPaneScaffold
и добавляет встроенную навигацию и предиктивную обработку возвратов.
Опорные леса для панелей поддерживают до трех панелей:
- Основная панель : отображает основное содержимое.
- Вспомогательная панель : предоставляет дополнительный контекст или инструменты, связанные с основной панелью.
- Дополнительная панель (необязательно) : используется для дополнительного содержимого при необходимости.
Леса адаптируются в зависимости от размера окна:
- В больших окнах основные и вспомогательные панели располагаются рядом.
В маленьких окнах одновременно видна только одна панель, которая переключается по мере перемещения пользователя.
Рисунок 1. Вспомогательная компоновка панели.
Добавить зависимости
NavigableSupportingPaneScaffold
является частью библиотеки адаптивной компоновки 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 : компонуемые элементы для навигации внутри панелей и между ними, а также адаптивные макеты, которые поддерживают навигацию по умолчанию, такие как
NavigableListDetailPaneScaffold
иNavigableSupportingPaneScaffold
Убедитесь, что ваш проект включает compose-material3-adaptive версии 1.1.0-beta1 или выше.
Включите функцию прогнозируемого жеста «назад»
Чтобы включить предиктивную анимацию «Назад» в Android 15 или более ранней версии, необходимо включить поддержку предиктивного жеста «Назад». Для этого добавьте android:enableOnBackInvokedCallback="true"
к тегу <application>
или отдельным тегам <activity>
в файле AndroidManifest.xml
.
Как только ваше приложение перейдет на Android 16 (уровень API 36) или выше, функция предиктивного возврата будет включена по умолчанию.
Создать навигатор
В небольших окнах одновременно отображается только одна панель, поэтому для перемещения между панелями используйте ThreePaneScaffoldNavigator
. Создайте экземпляр навигатора с помощью rememberSupportingPaneScaffoldNavigator
.
val scaffoldNavigator = rememberSupportingPaneScaffoldNavigator() val scope = rememberCoroutineScope()
Передайте навигатор на эшафот
Для скаффолда требуется ThreePaneScaffoldNavigator
, который является интерфейсом, представляющим состояние скаффолда, ThreePaneScaffoldValue
и PaneScaffoldDirective
.
NavigableSupportingPaneScaffold( navigator = scaffoldNavigator, mainPane = { /*...*/ }, supportingPane = { /*...*/ }, )
Основная и вспомогательная панели — это компонуемые элементы, содержащие ваш контент. Используйте AnimatedPane
для применения анимации панелей по умолчанию во время навигации. Используйте значение scaffold, чтобы проверить, скрыта ли вспомогательная панель; если да, отобразите кнопку, вызывающую navigateTo(SupportingPaneScaffoldRole.Supporting)
, для отображения вспомогательной панели.
Вот полная реализация каркаса:
val scaffoldNavigator = rememberSupportingPaneScaffoldNavigator() val scope = rememberCoroutineScope() NavigableSupportingPaneScaffold( navigator = scaffoldNavigator, mainPane = { AnimatedPane( modifier = Modifier .safeContentPadding() .background(Color.Red) ) { if (scaffoldNavigator.scaffoldValue[SupportingPaneScaffoldRole.Supporting] == PaneAdaptedValue.Hidden) { Button( modifier = Modifier .wrapContentSize(), onClick = { scope.launch { scaffoldNavigator.navigateTo(SupportingPaneScaffoldRole.Supporting) } } ) { Text("Show supporting pane") } } else { Text("Supporting pane is shown") } } }, supportingPane = { AnimatedPane(modifier = Modifier.safeContentPadding()) { Text("Supporting pane") } } )
Извлечь компонуемые панели
Извлеките отдельные панели SupportingPaneScaffold
в отдельные компонуемые объекты, чтобы сделать их пригодными для повторного использования и тестирования. Используйте ThreePaneScaffoldScope
для доступа к AnimatedPane
, если вам нужны анимации по умолчанию:
@OptIn(ExperimentalMaterial3AdaptiveApi::class) @Composable fun ThreePaneScaffoldPaneScope.MainPane( shouldShowSupportingPaneButton: Boolean, onNavigateToSupportingPane: () -> Unit, modifier: Modifier = Modifier, ) { AnimatedPane( modifier = modifier.safeContentPadding() ) { // Main pane content if (shouldShowSupportingPaneButton) { Button(onClick = onNavigateToSupportingPane) { Text("Show supporting pane") } } else { Text("Supporting pane is shown") } } } @OptIn(ExperimentalMaterial3AdaptiveApi::class) @Composable fun ThreePaneScaffoldPaneScope.SupportingPane( modifier: Modifier = Modifier, ) { AnimatedPane(modifier = modifier.safeContentPadding()) { // Supporting pane content Text("This is the supporting pane") } }
Извлечение панелей в составные элементы упрощает использование SupportingPaneScaffold
(сравните следующее с полной реализацией каркаса в предыдущем разделе):
val scaffoldNavigator = rememberSupportingPaneScaffoldNavigator() val scope = rememberCoroutineScope() NavigableSupportingPaneScaffold( navigator = scaffoldNavigator, mainPane = { MainPane( shouldShowSupportingPaneButton = scaffoldNavigator.scaffoldValue.secondary == PaneAdaptedValue.Hidden, onNavigateToSupportingPane = { scope.launch { scaffoldNavigator.navigateTo(ThreePaneScaffoldRole.Secondary) } } ) }, supportingPane = { SupportingPane() }, )
Если вам нужен больший контроль над отдельными аспектами скаффолда, рассмотрите возможность использования SupportingPaneScaffold
вместо NavigableSupportingPaneScaffold
. Этот метод принимает PaneScaffoldDirective
и ThreePaneScaffoldValue
или ThreePaneScaffoldState
по отдельности. Эта гибкость позволяет реализовать собственную логику для расстановки панелей и определить, сколько панелей должно отображаться одновременно. Вы также можете включить предиктивную поддержку обратного отображения, добавив ThreePaneScaffoldPredictiveBackHandler
.
Добавить ThreePaneScaffoldPredictiveBackHandler
Добавьте предиктивный обработчик обратных переходов, который принимает экземпляр навигатора Scaffold и указывает свойство backBehavior
. Это определяет, как пункты назначения извлекаются из стека обратных переходов во время обратной навигации. Затем передайте scaffoldDirective
и scaffoldState
в SupportingPaneScaffold
. Используйте перегрузку, которая принимает ThreePaneScaffoldState
, передавая scaffoldNavigator.scaffoldState
.
Определите основную и вспомогательную панели в SupportingPaneScaffold
. Используйте AnimatedPane
для анимации панелей по умолчанию.
После выполнения этих шагов ваш код должен выглядеть примерно так:
val scaffoldNavigator = rememberSupportingPaneScaffoldNavigator() val scope = rememberCoroutineScope() ThreePaneScaffoldPredictiveBackHandler( navigator = scaffoldNavigator, backBehavior = BackNavigationBehavior.PopUntilScaffoldValueChange ) SupportingPaneScaffold( directive = scaffoldNavigator.scaffoldDirective, scaffoldState = scaffoldNavigator.scaffoldState, mainPane = { MainPane( shouldShowSupportingPaneButton = scaffoldNavigator.scaffoldValue.secondary == PaneAdaptedValue.Hidden, onNavigateToSupportingPane = { scope.launch { scaffoldNavigator.navigateTo(ThreePaneScaffoldRole.Secondary) } } ) }, supportingPane = { SupportingPane() }, )