Android Academy · 课时

底部导航

构建带标签页的底部导航

第 4 / 4 课13 个步骤

底部导航 是 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 反馈 — 无需本地设置。

此课程中的所有课时

  1. 设置 NavHost
  2. 在屏幕之间导航
  3. 传递参数
  4. 底部导航
← 返回 Android Academy