在抽屉式导航栏中创建群组

导航抽屉组件是一个滑动式菜单,可让用户导航到应用的各个部分。用户可以通过从侧边滑动或点按菜单图标来激活该组件。
请考虑以下三种实现导航抽屉的使用情形:
内容组织:让用户能够在不同类别之间切换,例如在新闻应用或博客应用中。
账号管理:在具有用户账号的应用中提供指向账号设置和个人资料部分的快捷链接。
功能发现:在单个菜单中整理多个功能和设置,以便用户在复杂的应用中发现和访问功能。
在 Material Design 中,抽屉式导航栏分为两种类型:
标准:与其他内容共享屏幕空间。
模态:显示在屏幕内其他内容的顶部。
图 1. 抽屉式导航栏示例。
示例
您可以使用 ModalNavigationDrawer 可组合项来实现抽屉式导航栏。
使用 drawerContent slot 提供 ModalDrawerSheet 并提供抽屉式导航栏的内容,如以下示例所示:
ModalNavigationDrawer(
drawerContent = {
ModalDrawerSheet {
Text("Drawer title", modifier = Modifier.padding(16.dp))
HorizontalDivider()
NavigationDrawerItem(
label = { Text(text = "Drawer Item") },
selected = false,
onClick = { /*TODO*/ }
)
// ...other drawer items
}
}
) {
// Screen content
}MaterialLayoutSnippets.kt
ModalNavigationDrawer 接受一些额外的抽屉式导航栏参数。例如,您可以使用 gesturesEnabled 参数来切换抽屉式导航栏是否响应拖动,如以下示例所示:
ModalNavigationDrawer(
drawerContent = {
ModalDrawerSheet {
// Drawer contents
}
},
gesturesEnabled = false
) {
// Screen content
}MaterialLayoutSnippets.kt
控制行为
如需控制抽屉的打开和关闭方式,请使用 DrawerState。您应使用 drawerState 参数将 DrawerState 传递给 ModalNavigationDrawer。
DrawerState 可提供对 open 和 close 函数的访问权限,以及对与当前抽屉式导航栏状态相关的属性的访问权限。这些挂起函数需要 CoroutineScope,您可以使用 rememberCoroutineScope 对其进行实例化。您还可以调用挂起函数来响应界面事件。
val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
val scope = rememberCoroutineScope()
ModalNavigationDrawer(
drawerState = drawerState,
drawerContent = {
ModalDrawerSheet { /* Drawer content */ }
},
) {
Scaffold(
floatingActionButton = {
ExtendedFloatingActionButton(
text = { Text("Show drawer") },
icon = { Icon(Icons.Filled.Add, contentDescription = "") },
onClick = {
scope.launch {
drawerState.apply {
if (isClosed) open() else close()
}
}
}
)
}
) { contentPadding ->
// Screen content
}
}MaterialLayoutSnippets.kt
在抽屉式导航栏中创建群组
以下代码段展示了如何创建包含部分和分隔线的详细导航抽屉:
@Composable
fun DetailedDrawerExample(
content: @Composable (PaddingValues) -> Unit
) {
val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
val scope = rememberCoroutineScope()
ModalNavigationDrawer(
drawerContent = {
ModalDrawerSheet {
Column(
modifier = Modifier.padding(horizontal = 16.dp)
.verticalScroll(rememberScrollState())
) {
Spacer(Modifier.height(12.dp))
Text("Drawer Title", modifier = Modifier.padding(16.dp), style = MaterialTheme.typography.titleLarge)
HorizontalDivider()
Text("Section 1", modifier = Modifier.padding(16.dp), style = MaterialTheme.typography.titleMedium)
NavigationDrawerItem(
label = { Text("Item 1") },
selected = false,
onClick = { /* Handle click */ }
)
NavigationDrawerItem(
label = { Text("Item 2") },
selected = false,
onClick = { /* Handle click */ }
)
HorizontalDivider(modifier = Modifier.padding(vertical = 8.dp))
Text("Section 2", modifier = Modifier.padding(16.dp), style = MaterialTheme.typography.titleMedium)
NavigationDrawerItem(
label = { Text("Settings") },
selected = false,
icon = { Icon(Icons.Outlined.Settings, contentDescription = null) },
badge = { Text("20") }, // Placeholder
onClick = { /* Handle click */ }
)
NavigationDrawerItem(
label = { Text("Help and feedback") },
selected = false,
icon = { Icon(Icons.AutoMirrored.Outlined.Help, contentDescription = null) },
onClick = { /* Handle click */ },
)
Spacer(Modifier.height(12.dp))
}
}
},
drawerState = drawerState
) {
Scaffold(
topBar = {
TopAppBar(
title = { Text("Navigation Drawer Example") },
navigationIcon = {
IconButton(onClick = {
scope.launch {
if (drawerState.isClosed) {
drawerState.open()
} else {
drawerState.close()
}
}
}) {
Icon(Icons.Default.Menu, contentDescription = "Menu")
}
}
)
}
) { innerPadding ->
content(innerPadding)
}
}
}NavigationDrawer.kt
代码要点
使用包含部分、分隔线和导航项的 Column 填充 drawerContent。
ModalDrawerSheet 为抽屉式导航栏提供 Material Design 样式。
HorizontalDivider 用于分隔抽屉中的各个部分。
ModalNavigationDrawer 会创建抽屉。
drawerContent 定义抽屉式导航栏的内容。
在 ModalDrawerSheet 内,Column 会垂直排列抽屉元素。
NavigationDrawerItem 可组合项表示抽屉中的各个项。
Scaffold 提供屏幕的基本结构,包括 TopAppBar。
TopAppBar 中的 navigationIcon 用于控制抽屉的打开和关闭状态。
结果
下图显示了抽屉打开时的外观,其中显示了各个部分和项目:
图 2. 打开的抽屉式导航栏,其中包含两个嵌套的群组。
其他资源
Material Design:抽屉式导航栏