简体   繁体   English

Jetpack Compose + Navigation - 使用 BottomNavBar 的嵌套导航

[英]Jetpack Compose + Navigation - Nested navigation with BottomNavBar

I'm trying to implement the following screen flow using Jetpack Compose + Jetpack Navigation:我正在尝试使用 Jetpack Compose + Jetpack Navigation 实现以下屏幕流程:

Navigation concept导航概念

Actually, i am able to code two singles cases:实际上,我可以编写两个单例:

  • SplashScreen --> HomeScreen (with no BottomNavBar) SplashScreen --> HomeScreen(没有 BottomNavBar)
  • HomeScreen (with BottomNavBar) --> Tabs主屏幕(带有 BottomNavBar)--> 选项卡

I'm not able to code the whole problem.我无法对整个问题进行编码。 In fact, i have an issue with the management of the NavHost.事实上,我对 NavHost 的管理有疑问。 In the first case (SplashScreen -> HomeScreen) i need to call the NavHost at a high scope:在第一种情况下(SplashScreen -> HomeScreen)我需要在 scope 高位调用 NavHost:

class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
        MyAppTheme {
            //init the Navigation Controller for screen navigation
            val navController = rememberNavController()

            //setup the Navigation Graph
            SetupNavGraph(navController)

while in the second case i need to call it in the innerPadding scope of the Scaffold composable:而在第二种情况下,我需要在Scaffold可组合项的innerPadding scope 中调用它:

fun MainScreen(navController: NavHostController) {

    Scaffold(
        bottomBar = {
            BottomNavBar(navController)
        }
    ) { //innerPadding scope
        //setup the Navigation Graph
        SetupNavGraph(navController)
    }
}

Please assume that SetupNavGraph() function works as intended (call NavHost to generate the navigation tree)请假设 SetupNavGraph SetupNavGraph() function 按预期工作(调用NavHost生成导航树)

  • I tried to use two NavHost without success.我尝试使用两个NavHost但没有成功。
  • If i setup the NavHost in setContent() i'm able to load the splashscreen and move to an empty BottomNavBar screen.如果我在setContent()中设置NavHost ,我就可以加载闪屏并移动到空的BottomNavBar屏幕。 If i click on the BottomNavElements i'm able to navigate to the child tabs (in the example above "Favorite","Music","Places", "News") but the BottomNavBar disappears如果我单击BottomNavElements ,我可以导航到子选项卡(在上面的示例中“收藏夹”、“音乐”、“地点”、“新闻”)但是BottomNavBar消失了
  • I cannot setup NavHost in the innerPadding scope because this is loaded only after switching to the main screen (in the example above "Favorite Tab" + BottomBarNav)我无法在innerPadding scope 中设置NavHost ,因为它仅在切换到主屏幕后才加载(在上面的示例中“Favorite Tab”+ BottomBarNav)

The only workaround i found is generating the BottomNavBar composable in each of the BottomNav child tabs, but this generates a visible transition effect that i would like to avoid and, generally, doesn't seem a good practice.我发现的唯一解决方法是在每个 BottomNav 子选项卡中生成BottomNavBar可组合项,但这会生成我想避免的可见过渡效果,而且通常这似乎不是一个好的做法。

Ok, i found a solution.好的,我找到了解决方案。 This are the steps to achieve the desired result:这是实现预期结果的步骤:

  1. Create two different NavGraph, one for Splash->MainScreen and the other for the BottomNavBar创建两个不同的 NavGraph,一个用于 Splash->MainScreen,另一个用于 BottomNavBar
const val ROOT_ROUTE = "root"

@Composable
fun SetupRootNavGraph(navController: NavHostController) {
    NavHost(
        navController = navController,
        startDestination = Screen.FirstScreen.route,
        route = ROOT_ROUTE
    ) {
        composable(Screen.FirstScreen.route) { FirstScreen(navController)}
        composable(Screen.SecondScreen.route) { MainScreen(navController)}
    }
}
const val BOTTOM_BAR_ROUTE = "bottomBar"

@Composable
fun SetupNavGraphBottomBar(navController: NavHostController) {
    NavHost(
        navController = navController,
        startDestination = BottomBarScreen.FirstElement.route,
        route = BOTTOM_BAR_ROUTE
    ) {
        composable(BottomBarScreen.FirstElement.route) { FirstElementScreen() }
        composable(BottomBarScreen.SecondElement.route) { SecondElementScreen() }
        composable(BottomBarScreen.ThirdElement.route) { ThirdElementScreen() }
    }
}
  1. Init the NavController and the RootNavGraph after setContent() in your MainActivity .MainActivity中的setContent()之后初始化NavControllerRootNavGraph This will be in charge of the SplashScreen -> MainScreen navigation tree.这将负责 SplashScreen -> MainScreen 导航树。
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyAppTheme {

                //init the Navigation Controller for screen navigation
                val navController = rememberNavController()

                //setup the Root Navigation Graph
                SetupRootNavGraph(navController)
            }
        }
    }
}
  1. Re-init the NavController in the Screen where you have your BottomNavBar ("MainScreen" in the example) and the assign to it the BottomNavGraph in the innerPadding scope.在您拥有 BottomNavBar(示例中的“MainScreen”)的屏幕中重新初始化NavController ,并在innerPadding BottomNavGraph中为其分配 BottomNavGraph。
@Composable
fun MainScreen(navController: NavHostController) {

    //Re-initialize the NavController to set a new NavGraph
    val navControllerBottomBar = rememberNavController()

    Scaffold(
        bottomBar = {
            BottomNavBar(navControllerBottomBar)
        }
    ) {
        //setup the Navigation Graph
        SetupNavGraphBottomBar(navControllerBottomBar, user)
    }
}

And this will work like charm!这会很有魅力! Of course you will need to structure your BottomNavBar in order to manage the navigation as documented on Official docs当然,您需要构建BottomNavBar以管理官方文档中记录的导航

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Jetpack Compose 嵌套导航和 BottomAppBar - Jetpack Compose nested navigation and BottomAppBar 将参数传递给 Jetpack Compose 中的嵌套导航图 - Pass an argument to a nested navigation graph in Jetpack Compose Jetpack Compose Navigation:直接导航以在不是 startDestination 的嵌套图中路由 - Jetpack Compose Navigation: Direct navigation to route in a nested graph which is not startDestination Jetpack Compose - 如果有嵌套导航,则不选择底部导航图标 - Jetpack Compose - Bottom navigation icon is not selected if it has nested navigation Jetpack 使用 viewModel 组合导航 - Jetpack compose navigation with viewModel Android Jetpack 撰写和导航 - Android Jetpack Compose and Navigation Jetpack Compose - 使用带有 BottomNavBar 的嵌套 NavGraph 并选择图标 - Jetpack Compose - Using Nested NavGraph with BottomNavBar and make Icons selected Android Jetpack Navigation如何处理Toolbar和BottomNavBar内容 - Android Jetpack Navigation How to handle the Toolbar and BottomNavBar content Jetpack Compose - 底部导航栏不显示嵌套的 navGraph - Jetpack Compose - Bottom navigation bar isn't showing with nested navGraph Jetpack compose - 使用 1.0.0-alpha02 嵌套导航 - Jetpack compose - nested navigation with 1.0.0-alpha02
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM