“列表-详情”是一种界面模式,由双窗格布局组成,其中一个窗格 会显示项目列表,而另一个窗格则显示所选项目的详细信息 。
这种模式特别适合 大型集合(例如电子邮件客户端)元素的相关信息 其中包含电子邮件列表和每封电子邮件的详细内容。 列表-详情也可用于不太重要的路径,例如划分应用 转换为类别列表,其中包含每个类别的 “详细信息”窗格
使用 ListDetailPaneScaffold
实现界面模式
ListDetailPaneScaffold
是一个可组合项,可简化
您的应用中的“列表-详情”模式“列表-详情”基架最多可包含
三个窗格:列表窗格、详细信息窗格和一个可选的额外窗格。通过
基架可用于处理屏幕空间的计算。当屏幕足够大时
详情窗格会显示在列表窗格旁边。在小屏幕上
Scaffold 会自动切换为显示列表或
全屏显示详情窗格。
声明依赖项
ListDetailPaneScaffold
是 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'
- 自适应 - 低层级构建块,例如
HingeInfo
和Posture
- adaptive-layout - 自适应布局,例如
ListDetailPaneScaffold
和SupportingPaneScaffold
- adaptive-navigation - 用于在和 在窗格之间
基本用法
按如下方式实现 ListDetailPaneScaffold
:
使用一个类来表示要选择的内容。此课程 应为
Parcelable
,以支持保存 以及恢复所选列表项使用 kotlin-parcelize 插件来为您生成代码。@Parcelize class MyItem(val id: Int) : Parcelable
使用以下代码创建一个
ThreePaneScaffoldNavigator
:rememberListDetailPaneScaffoldNavigator
并添加BackHandler
。这个 导航器用于在列表窗格、详情窗格和其他窗格之间移动。修改者 声明泛型类型时,导航器也会跟踪 基架(即正在显示的MyItem
)。由于此类型 parcelable,因此导航器可以保存并恢复状态, 自动处理配置更改。通过BackHandler
支持使用系统返回手势或 按钮。返回按钮的预期行为ListDetailPaneScaffold
取决于窗口大小和当前 Scaffold 值。如果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
属性与原始 remember 调用中指定的类型相同 (在此示例中为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) } } }, )