Jetpack Compose 中带有底部栏的嵌套导航

问题描述 投票:0回答:1

我有一个包含以下代码的 RootGraph:

@Composable
fun RootNavGraph(navController: NavHostController) {
    NavHost(
        navController = navController,
        startDestination = CommonRoute.Splash.route,
        route = GeneralGraph.ROOT
    ) {
        composable(CommonRoute.Splash.route) { SplashScreen(navController = navController) }
        authNavigation(navController)
        composable(CommonRoute.MainBody.route) {
            MainBody()
        }
    }
}

我想创建一个登录流程,当您的会话过期时,人们会希望从底部图表导航回根图表。

@Composable
fun MainBody(navController: NavHostController = rememberNavController()) {
    Scaffold(
        bottomBar = {
            CustomBottomBar(navController = navController)
        }
    ) {
        Surface(
            modifier = Modifier
                .padding(it)
                .fillMaxSize()
        ) {
            MainNavGraph(navController)
        }
    }
}


@Composable
fun MainNavGraph(navController: NavHostController) {
    NavHost(
        navController = navController,
        startDestination = MainGraph.MAIN,
        route = GeneralGraph.MAIN
    ) {
        mainNavigation(navController = navController)
    }
}

fun NavGraphBuilder.mainNavigation(navController: NavHostController) {
    navigation(route = MainGraph.MAIN, startDestination = MainRoute.Home.route) {
        composable(MainRoute.Home.route) {
            HomeScreen(
                navController = navController,
                onUserNotRegistered = {
                    navController.navigate(GeneralGraph.AUTH) {
                        popUpTo(navController.graph.findStartDestination().id)
                    }
                }
            )
        }
        composable(MainRoute.Post.route) { PostScreen(navController = navController) }
        composable(MainRoute.Profile.route) {
            //val viewModel: ProfileViewModel = hiltViewModel()
            ProfileScreen(navController = navController, onSignOut = { })
        }
    }
}

一开始,它会加载启动屏幕并转到主屏幕以检查用户是否存在,否则我希望它将我发送到身份验证图。 同样,当我从底部栏选项中的个人资料屏幕注销时,它会将我发送到身份验证图。

android navigation android-jetpack-compose
1个回答
0
投票

首先将以下代码放入主活动中

val navController = rememberNavController()
RootNavigationGraph(navController = navController)

创建新的 RootNavigationGraph.kt 并放入以下代码

@Composable
    fun RootNavigationGraph(navController: NavHostController) {
        NavHost(
            navController = navController,
            startDestination = Screen.Login.route
        ) {
            composable(Screen.Login.route) {
                PhoneLoginScreen(navController = navController)
            }
            composable(Screen.Home.route) {
                BottomNavigationScreen(rootNavController = navController)
            }
        }
    }

创建新的 BottomNavigationScreen.kt 并放入以下代码

@Composable
fun BottomNavigationScreen(rootNavController: NavController) {
    val navController = rememberNavController()
    val scaffoldState = rememberScaffoldState(
        drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
    )

    val activity = LocalContext.current as Activity
    val navBackStackEntry by navController.currentBackStackEntryAsState()
    val currentRoute = navBackStackEntry?.destination
    BackHandler {
        if (currentRoute?.route == BottomNavigationItem.HOME.route){
            activity.finish()
        }
    }

    Scaffold(
        scaffoldState = scaffoldState,
        bottomBar = { CustomBottomNavigation(navController = navController) }
    ) {
        Box(modifier = androidx.compose.ui.Modifier.padding(it)) {
            BottomNavigationGraph(
                navController = navController
            )
        }
    }
}

创建新的 BottomNavigationGraph.kt 并放入以下代码

@Composable
fun BottomNavigationGraph(
    navController: NavHostController,
) {
    NavHost(
        navController = navController,
        startDestination = Constants.BottomNavigationItemRoute.HOME
    ) {
        composable(BottomNavigationItem.HOME.route) {
            HomeScreen()
        }
        composable(BottomNavigationItem.PEOPLE.route) {
            // other composable screen
        }
        composable(BottomNavigationItem.TASKS.route) {
            // other composable screen
        }
    }
}

创建新的 CustomBottomNavigation.kt 并放入以下代码

@Composable
fun CustomBottomNavigation(navController: NavController) {
    val items = mutableListOf(
        BottomNavigationItem.HOME,
        BottomNavigationItem.PEOPLE,
        BottomNavigationItem.TASKS
    )
    val navBackStackEntry by navController.currentBackStackEntryAsState()
    val currentRoute = navBackStackEntry?.destination
    BottomNavigation {
        items.forEach { item ->
            BottomNavigationItem(
                icon = {
                    Icon(
                        painter = painterResource(id = item.icon),
                        contentDescription = item.title
                    )
                },
                label = {
                    Text(
                        text = item.title,
                        fontWeight = FontWeight.Normal,
                        fontSize = 10.sp,
                        style = TextStyle(letterSpacing = 1.8.sp),
                        maxLines = 1
                    )
                },
                selectedContentColor = Secondary,
                unselectedContentColor = White,
                alwaysShowLabel = true,
                selected = currentRoute?.route == item.route,
                onClick = {
                    navController.navigate(item.route) {
                        popUpTo(navController.graph.findStartDestination().id) {
                            inclusive = false
                            saveState = false
                        }
                        launchSingleTop = true
                        restoreState = false
                    }
                }
            )
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.