支持面板规范布局将用户注意力集中在您应用程序的主要内容上,同时还显示相关的辅助内容。 例如,主内容面板可能显示有关最近电影的信息,而支持面板显示具有相似主题或相同导演或主演演员的其他电影列表。 有关支持面板规范布局的更多信息,请参阅 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'
- adaptive — 低级构建块,例如
HingeInfo
和Posture
- adaptive-layout — 自适应布局,例如
SupportingPaneScaffold
- 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() }, )