大多数应用都有多个顶级目的地,可通过 应用的主要导航界面。在较小的窗口中,例如标准手机 目的地通常显示在 窗口底部在展开的窗口(例如设备上的全屏应用)中, 通常来说,与应用相邻的侧边导航栏通常是更好的选择 在按住屏幕的左右两侧时,更易于使用导航控件 设备的实际情况
NavigationSuiteScaffold
简化了切换流程
通过显示适当的导航界面可组合项,在导航界面之间实现无缝切换。
来自WindowSizeClass
。其中包括
在运行时窗口大小发生变化时更改界面。默认情况下
显示以下任一界面组件:
- 导航栏:如果宽度或高度比较紧凑,或者设备在 桌面折叠状态
- 所有其他内容的侧边导航栏
![](https://developer.android.google.cn/static/develop/ui/compose/images/layouts/adaptive/navigationsuitescaffold_with_nav_bar.png?authuser=0000&hl=fi)
NavigationSuiteScaffold
在紧凑窗口中显示导航栏。
![](https://developer.android.google.cn/static/develop/ui/compose/images/layouts/adaptive/navigationsuitescaffold_with_nav_rail.png?authuser=0000&hl=fi)
NavigationSuiteScaffold
在展开的窗口中显示侧边导航栏。
添加依赖项
NavigationSuiteScaffold
是
Material3 自适应导航套件
库。在应用的 build.gradle
文件中为该库添加依赖项
或模块:
Kotlin
implementation("androidx.compose.material3:material3-adaptive-navigation-suite")
Groovy
implementation 'androidx.compose.material3:material3-adaptive-navigation-suite'
创建 Scaffold
NavigationSuiteScaffold
的两个主要部分是导航套件项
以及所选目标页面的内容。您可以直接定义
可组合项中的导航套件项,但定义这些项的情况很常见
在其他位置(例如在枚举中):
enum class AppDestinations( @StringRes val label: Int, val icon: ImageVector, @StringRes val contentDescription: Int ) { HOME(R.string.home, Icons.Default.Home, R.string.home), FAVORITES(R.string.favorites, Icons.Default.Favorite, R.string.favorites), SHOPPING(R.string.shopping, Icons.Default.ShoppingCart, R.string.shopping), PROFILE(R.string.profile, Icons.Default.AccountBox, R.string.profile), }
如需使用 NavigationSuiteScaffold
,您必须跟踪当前目的地,
您可以使用 rememberSaveable
来实现此目的:
var currentDestination by rememberSaveable { mutableStateOf(AppDestinations.HOME) }
在以下示例中,navigationSuiteItems
参数(类型
NavigationSuiteScope
使用其 item
函数
定义单个目的地的导航界面。目标界面是
用于导航栏、侧边栏和抽屉式导航栏中。要创建导航项,您需要
循环遍历您的 AppDestinations
(在前面的代码段中定义):
NavigationSuiteScaffold( navigationSuiteItems = { AppDestinations.entries.forEach { item( icon = { Icon( it.icon, contentDescription = stringResource(it.contentDescription) ) }, label = { Text(stringResource(it.label)) }, selected = it == currentDestination, onClick = { currentDestination = it } ) } } ) { // TODO: Destination content. }
在目的地内容 lambda 中,使用 currentDestination
值执行以下操作
决定要显示的界面如果您在应用中使用导航库,请使用该库
显示相应的目标位置。when 语句便足以满足需求:
NavigationSuiteScaffold( navigationSuiteItems = { /*...*/ } ) { // Destination content. when (currentDestination) { AppDestinations.HOME -> HomeDestination() AppDestinations.FAVORITES -> FavoritesDestination() AppDestinations.SHOPPING -> ShoppingDestination() AppDestinations.PROFILE -> ProfileDestination() } }
更改颜色
NavigationSuiteScaffold
会在整个区域上创建一个 Surface
Scaffold 所占空间,通常是整个窗口。最重要的是,基架
用于绘制特定导航界面,例如 NavigationBar
。
Surface 和导航界面都使用在应用的
主题,但您可以替换主题值。
containerColor
参数用于指定 Surface 的颜色。默认
是配色方案的背景颜色。contentColor
参数
用于指定该 surface 上内容的颜色。默认值为“启用”颜色
任何为 containerColor
指定的值。例如,如果 containerColor
使用 background
颜色,contentColor
则使用 onBackground
颜色。
请参阅 Compose 中的 Material Design 3 主题设置
了解有关颜色系统工作原理的更多详情。替换这些值时
使用主题中定义的值,以便应用支持深色显示和浅色显示
模式:
NavigationSuiteScaffold( navigationSuiteItems = { /* ... */ }, containerColor = MaterialTheme.colorScheme.primary, contentColor = MaterialTheme.colorScheme.onPrimary, ) { // Content... }
导航界面在 NavigationSuiteScaffold
Surface 前面绘制。
界面颜色的默认值由
NavigationSuiteDefaults.colors()
,但你
也可以覆盖这些值例如,如果您希望
导航栏是透明的,其他值则设为默认值
替换 navigationBarContainerColor
:
NavigationSuiteScaffold( navigationSuiteItems = { /* ... */ }, navigationSuiteColors = NavigationSuiteDefaults.colors( navigationBarContainerColor = Color.Transparent, ) ) { // Content... }
最终,您可以自定义导航界面中的每项内容。在调用
item
函数,您可以传入
NavigationSuiteItemColors
。该类指定了
导航栏、侧边导航栏和导航栏中的项的颜色
抽屉式导航栏。也就是说,每种导航界面类型都可以采用相同的颜色,
也可以根据需要更改颜色定义
NavigationSuiteScaffold
级别对所有商品使用同一对象实例
并调用 NavigationSuiteDefaults.itemColors()
函数,以仅替换
你要更改的对象:
val myNavigationSuiteItemColors = NavigationSuiteDefaults.itemColors( navigationBarItemColors = NavigationBarItemDefaults.colors( indicatorColor = MaterialTheme.colorScheme.primaryContainer, selectedIconColor = MaterialTheme.colorScheme.onPrimaryContainer ), ) NavigationSuiteScaffold( navigationSuiteItems = { AppDestinations.entries.forEach { item( icon = { Icon( it.icon, contentDescription = stringResource(it.contentDescription) ) }, label = { Text(stringResource(it.label)) }, selected = it == currentDestination, onClick = { currentDestination = it }, colors = myNavigationSuiteItemColors, ) } }, ) { // Content... }
自定义导航类型
NavigationSuiteScaffold
的默认行为会更改导航界面
基于窗口大小
类。不过,您
您可能需要覆盖此行为例如,如果您的应用显示了一个
显示大尺寸内容窗格,则应用可以使用永久性导航
但对于展开后的窗口,则仍然会采用默认行为
较小和中等窗口大小类别:
val adaptiveInfo = currentWindowAdaptiveInfo() val customNavSuiteType = with(adaptiveInfo) { if (windowSizeClass.windowWidthSizeClass == WindowWidthSizeClass.EXPANDED) { NavigationSuiteType.NavigationDrawer } else { NavigationSuiteScaffoldDefaults.calculateFromAdaptiveInfo(adaptiveInfo) } } NavigationSuiteScaffold( navigationSuiteItems = { /* ... */ }, layoutType = customNavSuiteType, ) { // Content... }
其他资源
请参阅 Material Design 指南:
请参阅以下 androidx.compose.material3
库组件: