BottomNavigationBar 中的 Jetpack Compose 导航问题

Eve*_*eam 5 android android-jetpack-navigation android-jetpack-compose

根据下图,我的应用程序当前包含 2 个主要路由:Auth 和 Dashboard。当用户启动应用程序时,观察者将检查用户是否已登录并将他/她引导至登录页面/仪表板。

导航流程

从图中你可以看到,我已经在 MainActivity 中设置了 NavGraph(包括所有仪表板路线)。问题是当用户单击底部导航项之一时,他/她将直接定向到视图页面。相反,我想要的是向用户展示仪表板支架内容内的视图。检查下图。

遇到的问题

根据这些信息,一旦用户单击该项目,如何获取脚手架内容内的可组合视图?

任何指导将不胜感激。谢谢!

旁注:这是我的第一个撰写项目,我试图在不使用任何片段的情况下实现单活动架构。如果我的代码违反了任何设计或编程约定,我事先表示歉意,因为我对编程还很陌生[这里是自学者,又名业余爱好者:(]。

MainActivity.kt

package com.example.firstcomposeproject

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.viewModels
import androidx.navigation.NavController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navigation
import com.example.firstcomposeproject.authview.FirebaseUserViewModel
import com.example.firstcomposeproject.authview.LogIn
import com.example.firstcomposeproject.authview.SignUpFragment
import com.example.firstcomposeproject.dashboard.*

import com.example.firstcomposeproject.ui.theme.FirstComposeProjectTheme


class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val userViewModel: FirebaseUserViewModel by viewModels()

        setContent {
            FirstComposeProjectTheme(
                darkTheme = false
            ) {
                val navController = rememberNavController()


                /*
                Observing FirebaseUser LiveData to check if user is logged in. If yes, direct user
                to dashboard, else direct user to authenticate screen.
                */
                userViewModel.userMutableLiveData.observe(this, {
                        firebaseUser ->
                    if(firebaseUser != null){
                        navController.popBackStack()
                        navController.navigate("dashboard"){
                            popUpTo("auth"){
                                inclusive = true
                            }
                        }

                        userViewModel.clearFormField()
                    }else {
                        navController.navigate("auth"){
                            popUpTo("dashboard"){
                                inclusive = true
                            }
                        }
                    }
                })


                //Navigation Graph For The Whole App
                NavHost(navController = navController, startDestination = "auth"){
                    navigation(startDestination = "logInUI", route = "auth"){
                        composable("logInUI"){
                            LogIn(
                                userViewModel,
                                onNavigate = {
                                    navigateTo(it, navController)
                                }
                            ).FinalView()
                        }

                        composable("signUpUI"){
                            SignUpFragment(
                                userViewModel,
                                onNavigate = {
                                    navigateTo(it, navController)
                                }
                            ).FinalView()
                        }
                    }
                    addDashBoardGraph(userViewModel, navController)
                }
            }
        }
    }

    private fun navigateTo(
        dest: String,
        navController: NavController
    ){
        navController.navigate(dest)
    }



}
Run Code Online (Sandbox Code Playgroud)

仪表板.kt

package com.example.firstcomposeproject.dashboard

import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.navigation.NavDestination.Companion.hierarchy
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.navigation
import com.example.firstcomposeproject.authview.FirebaseUserViewModel
import com.example.firstcomposeproject.dashboard.helper.Screen

import com.example.firstcomposeproject.ui.theme.Teal200

fun NavGraphBuilder.addDashBoardGraph(
    userViewModel: FirebaseUserViewModel,
    navController: NavHostController
  ) {
    navigation(startDestination = "dashboardUI", route = "dashboard"){
        composable("dashboardUI"){
            Dashboard(
                navController,
                userViewModel
            )
        }

        composable("navigationUI"){
            Navigation()
        }

        composable("messageUI"){
            Message()
        }

        composable("historyUI"){
            History()
        }

        composable("profileUI"){
            Profile(
                userViewModel
            )
        }
    }
}


@Composable
fun Dashboard(
    navController: NavHostController,
    userViewModel: FirebaseUserViewModel
){
    val items = listOf(
        Screen.Navigation,
        Screen.Message,
        Screen.History,
        Screen.Profile
    )

    Scaffold(
        bottomBar = {
            BottomNavigation(
                backgroundColor = Color.White,
                contentColor = Teal200
            ) {
                val navBackStackEntry by navController.currentBackStackEntryAsState()
                val currentDestination = navBackStackEntry?.destination

                items.forEach{ screen ->
                    BottomNavigationItem(
                        label = { Text(text = screen.label)},
                        selected = currentDestination?.hierarchy?.any{ it.route == screen.route } == true,
                        onClick = {
                            navController.navigate(screen.route)
                            {

                                popUpTo(navController.graph.findStartDestination().id) {
                                    saveState = true
                                }
                                launchSingleTop = true

                                restoreState = true
                            }
                        },
                        icon = {
                            Icon(painterResource(id = screen.icon), screen.label)
                        }, unselectedContentColor = Color.Gray
                    )
                }

            }
        }
    ){
        //Scaffold Content - How to access the compose function from the MainActivity NavGraph here?
     }
}
Run Code Online (Sandbox Code Playgroud)

Ste*_*one 1

查看您的代码,我认为您需要在仪表板功能中的内容NavHost中设置 a Scaffold,以告诉系统您想要使用bottomBar您创建的布局在布局内切换可组合项。

我发现您已经了解嵌套导航,因此如果您只想重用相同的内容,NavHost您可以尝试在特定的可组合函数中定义它。

@Composable
fun MyNavGraph(
    navController: NavHostController = rememberNavController(),
    userViewModel: FirebaseUserViewModel
){
    NavHost(navController = navController, startDestination = "auth"){
        navigation(startDestination = "logInUI", route = "auth"){
            composable("logInUI"){
                LogIn(
                    userViewModel,
                    onNavigate = {
                        navigateTo(it, navController)
                    }
                ).FinalView()
            }

            composable("signUpUI"){
                SignUpFragment(
                    userViewModel,
                    onNavigate = {
                        navigateTo(it, navController)
                    }
                ).FinalView()
            }
        }
        addDashBoardGraph(userViewModel, navController)
    }
}


Run Code Online (Sandbox Code Playgroud)

我没有尝试过,所以请告诉我是否适合您的情况。希望有一点帮助。