底部导航
构建带标签页的底部导航
底部导航 是 CoddyKit 上的免费 Android Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Android Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Android Academy 课程共包含 4 节课。
底部导航栏
许多应用会将顶级部分放在底部导航栏中。Compose 提供了 NavigationBar 和 NavigationBarItem 来实现这一功能。
NavigationBar
NavigationBar 是容器,通常放置在 Scaffold 的 bottomBar 插槽中。它包含多个 NavigationBarItem。
NavigationBar {
// items go here
}NavigationBarItem
每个标签页都是一个 NavigationBarItem,包含 icon、可选的 label、selected 标志和 onClick。
NavigationBarItem(
selected = true,
onClick = { },
icon = { Icon(Icons.Default.Home, contentDescription = "Home") },
label = { Text("Home") }
)对标签页进行建模
将标签页定义为数据,这样您就可以遍历它们。包含路由、标签和图标的简单数据类就很适用。
data class Tab(val route: String, val label: String, val icon: ImageVector)
val tabs = listOf(
Tab("home", "Home", Icons.Default.Home),
Tab("profile", "Profile", Icons.Default.Person)
)跟踪当前路由
要突出显示当前标签页,您需要知道当前路由。请从控制器的当前返回栈条目中读取它。
val backStackEntry by navController.currentBackStackEntryAsState()
val currentRoute = backStackEntry?.destination?.route标记选中状态
将每个标签页的路由与 currentRoute 比较,以设置 selected 标志,这样导航栏就会突出显示正确的项目。
NavigationBarItem(
selected = currentRoute == tab.route,
onClick = { navController.navigate(tab.route) },
icon = { Icon(tab.icon, contentDescription = tab.label) },
label = { Text(tab.label) }
)避免返回栈堆积
反复点击标签页不应堆积目标。标签页之间导航时,请使用 popUpTo 返回起始目标,并结合 launchSingleTop。
navController.navigate(tab.route) {
popUpTo(navController.graph.startDestinationId) { saveState = true }
launchSingleTop = true
restoreState = true
}saveState / restoreState
当您离开某个标签页再返回时,saveState 和 restoreState 会保留该标签页的滚动位置和状态,这正是底部标签页应有的行为。
集成 Scaffold
将所有内容包裹在 Scaffold 中。将导航栏放入 bottomBar,将 NavHost 放入内容区域,并使用提供的内边距,以免内容被导航栏遮挡。
Scaffold(
bottomBar = { BottomBar(navController) }
) { padding ->
NavHost(
navController,
startDestination = "home",
modifier = Modifier.padding(padding)
) { /* destinations */ }
}遍历项目
通过遍历标签页列表来构建导航栏,这样代码更简短,也更一致。
NavigationBar {
tabs.forEach { tab ->
NavigationBarItem(
selected = currentRoute == tab.route,
onClick = { navController.navigate(tab.route) },
icon = { Icon(tab.icon, contentDescription = tab.label) },
label = { Text(tab.label) }
)
}
}整合应用
将完整的底部导航栏连接到控制器,并突出显示当前标签页。
@Composable
fun BottomBar(navController: NavController) {
val entry by navController.currentBackStackEntryAsState()
val current = entry?.destination?.route
NavigationBar {
tabs.forEach { tab ->
NavigationBarItem(
selected = current == tab.route,
onClick = { navController.navigate(tab.route) },
icon = { Icon(tab.icon, contentDescription = tab.label) },
label = { Text(tab.label) }
)
}
}
}快速检查
如何确定要将哪个 NavigationBarItem 标记为 selected?
回顾
底部导航:
NavigationBar包含NavigationBarItem。- 通过
currentBackStackEntryAsState()跟踪当前标签页,并设置selected。 - 使用
popUpTo+launchSingleTop+saveState/restoreState,实现整洁的标签页切换。 - 将其放入
Scaffold的bottomBar中。
用 AI 导师学习 Kotlin — 免费
在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。
- 课程
- 36
- 课程
- 152
常见问题解答
「底部导航」课时是免费的吗?
是的 — 「底部导航」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Android Academy 课程的其余内容,请升级到 CoddyKit PRO。 Android Academy 课程共包含 4 节课。
「底部导航」这节课中我会学到什么?
构建带标签页的底部导航 你通过在浏览器中直接运行的动手代码来练习 Android Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Android Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Android Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「底部导航」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Android Academy 课中编写并运行代码吗?
能。每节 Android Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。