Jetpack compose嵌套导航

准确的说是一个stack导航里嵌套了一个tab导航。这个时候按照文档的方法会报错。所以需要用到两个NavHost来处理。代码在这里。APP的导航是这样的:

点了首页的todo item后跳转到todo的详情页,这个时候整个的tab都不可见。

先看tab navigator。这是是一个底部的tab。代码如下:

kotlin 复制代码
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TabScreen(outerNav: NavHostController) {
    val navController = rememberNavController()
    val tabBarItems = listOf(
        Screens.Home,
        Screens.Settings,
    )
    val navBackStackEntry by navController.currentBackStackEntryAsState()

    Scaffold(topBar = {
        TopAppBar(
            // removed
        )
    }, bottomBar = {
        BottomTabBar(navController = navController, items = tabBarItems)
    }) { innerPadding ->
        NavHost(
            navController = navController,
            startDestination = Screens.Home.route,
            Modifier.padding(innerPadding)
        ) {
            composable(Screens.Home.route) {
                HomeScreen(
                    outerNav = outerNav,
                    navController = navController
                )
            }
            composable(Screens.Settings.route) {
                SettingsScreen(
                    navController = navController,
                )
            }
            composable(
                route = Screens.AddTodo.route, // TODO: enter & exit transition?
            ) { AddTodoScreen(navController = navController) }
        }
    }
}

删掉了一些不必要的代码,但是不影响阅读。

TabScreen接收一个参数outerNav,这个参数随后会传入Tab导航的第一个screen也就是HomeScreen。这样在首页点击一个todo条目的时候就可以使用外部的导航来跳转页面。

现在看看外面的导航,其实很简单:

kotlin 复制代码
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MainScreen(settingsViewModel: SettingsViewModel = hiltViewModel()) {
    val navController = rememberNavController()

    NavHost(navController = navController, startDestination = "main") {
        composable(route = "main") {
            TabScreen(outerNav = navController)
        }

        composable(route = "${Screens.Detail.route}/{todoId}") { backStackEntry ->
            DetailScreen(
                navController = navController,
                backStackEntry.arguments?.getString("todoId")?.toIntOrNull()
            )
        }
    }
}

在tab导航使用的外部导航outerNav就是在这里创建的,然后传给了TabScreen

总结一下,外部的stack导航的navigator传给嵌套的tab导航,然后再传递给tab导航的首页。并在首页里使用外部的导航跳转stack导航的页面。

相关推荐
大白要努力!6 分钟前
Android opencv使用Core.hconcat 进行图像拼接
android·opencv
天空中的野鸟1 小时前
Android音频采集
android·音视频
小白也想学C2 小时前
Android 功耗分析(底层篇)
android·功耗
曙曙学编程2 小时前
初级数据结构——树
android·java·数据结构
闲暇部落4 小时前
‌Kotlin中的?.和!!主要区别
android·开发语言·kotlin
诸神黄昏EX6 小时前
Android 分区相关介绍
android
大白要努力!7 小时前
android 使用SQLiteOpenHelper 如何优化数据库的性能
android·数据库·oracle
Estar.Lee7 小时前
时间操作[取当前北京时间]免费API接口教程
android·网络·后端·网络协议·tcp/ip
Winston Wood8 小时前
Perfetto学习大全
android·性能优化·perfetto
Dnelic-11 小时前
【单元测试】【Android】JUnit 4 和 JUnit 5 的差异记录
android·junit·单元测试·android studio·自学笔记