支持面板规范布局将用户的注意力集中在您应用的主要内容上,同时还显示相关的辅助内容。例如,主要内容面板可能会显示有关最近电影的信息,而辅助面板则显示具有类似主题或相同导演或主演的其它电影列表。有关支持面板规范布局的更多信息,请参阅Material 3 支持面板指南。
实现支持面板
SupportingPaneScaffold
最多包含三个面板:主面板、支持面板和可选的额外面板。该脚手架处理所有用于将窗口空间分配给这三个面板的计算。在大屏幕上,脚手架显示主面板,辅助面板位于侧面。在小屏幕上,脚手架显示全屏的主面板或辅助面板。
添加依赖项
SupportingPaneScaffold
是Material 3 自适应布局库的一部分。
将以下三个相关的依赖项添加到您的应用或模块的build.gradle
文件中
Kotlin
implementation("androidx.compose.material3.adaptive:adaptive") implementation("androidx.compose.material3.adaptive:adaptive-layout") implementation("androidx.compose.material3.adaptive:adaptive-navigation")
Groovy
implementation 'androidx.compose.material3.adaptive:adaptive' implementation 'androidx.compose.material3.adaptive:adaptive-layout' implementation 'androidx.compose.material3.adaptive:adaptive-navigation'
创建导航器和脚手架
在小窗口中,一次只显示一个面板,因此请使用ThreePaneScaffoldNavigator
在面板之间移动。使用rememberSupportingPaneScaffoldNavigator
创建导航器的实例。要处理返回手势,请使用一个BackHandler
,它检查canNavigateBack()
并调用navigateBack()
val navigator = rememberSupportingPaneScaffoldNavigator() BackHandler(navigator.canNavigateBack()) { navigator.navigateBack() }
脚手架需要一个PaneScaffoldDirective
,它控制如何分割屏幕以及使用多少间距,以及一个ThreePaneScaffoldValue
,它提供面板的当前状态(例如它们是展开还是隐藏)。对于默认行为,请分别使用导航器的scaffoldDirective
和scaffoldValue
SupportingPaneScaffold( directive = navigator.scaffoldDirective, value = navigator.scaffoldValue, mainPane = { /*...*/ }, supportingPane = { /*...*/ }, )
主面板和辅助面板是包含您内容的可组合项。使用AnimatedPane
在导航期间应用默认面板动画。使用脚手架值检查辅助面板是否隐藏;如果是,则显示一个按钮,该按钮调用navigateTo(ThreePaneScaffoldRole.Secondary)
以显示辅助面板。
以下是脚手架的完整实现
val navigator = rememberSupportingPaneScaffoldNavigator() BackHandler(navigator.canNavigateBack()) { navigator.navigateBack() } SupportingPaneScaffold( directive = navigator.scaffoldDirective, value = navigator.scaffoldValue, mainPane = { AnimatedPane(modifier = Modifier.safeContentPadding()) { // Main pane content if (navigator.scaffoldValue[SupportingPaneScaffoldRole.Supporting] == PaneAdaptedValue.Hidden) { Button( modifier = Modifier.wrapContentSize(), onClick = { navigator.navigateTo(SupportingPaneScaffoldRole.Supporting) } ) { Text("Show supporting pane") } } else { Text("Supporting pane is shown") } } }, supportingPane = { AnimatedPane(modifier = Modifier.safeContentPadding()) { // Supporting pane content Text("Supporting pane") } }, )
提取面板可组合项
将SupportingPaneScaffold
的各个面板提取到它们自己的可组合项中,以使其可重用和可测试。如果您想要默认动画,请使用ThreePaneScaffoldScope
访问AnimatedPane
@Composable fun ThreePaneScaffoldScope.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") } } } @Composable fun ThreePaneScaffoldScope.SupportingPane( modifier: Modifier = Modifier, ) { AnimatedPane(modifier = modifier.safeContentPadding()) { // Supporting pane content Text("This is the supporting pane") } }
将面板提取到可组合项中简化了SupportingPaneScaffold
的使用(将以下内容与上一节中脚手架的完整实现进行比较)
val navigator = rememberSupportingPaneScaffoldNavigator() BackHandler(navigator.canNavigateBack()) { navigator.navigateBack() } SupportingPaneScaffold( directive = navigator.scaffoldDirective, value = navigator.scaffoldValue, mainPane = { MainPane( shouldShowSupportingPaneButton = navigator.scaffoldValue.secondary == PaneAdaptedValue.Hidden, onNavigateToSupportingPane = { navigator.navigateTo(ThreePaneScaffoldRole.Secondary) } ) }, supportingPane = { SupportingPane() }, )