簡體   English   中英

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

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

我正在嘗試使用 Jetpack Compose + Jetpack Navigation 實現以下屏幕流程:

導航概念

實際上,我可以編寫兩個單例:

  • SplashScreen --> HomeScreen(沒有 BottomNavBar)
  • 主屏幕(帶有 BottomNavBar)--> 選項卡

我無法對整個問題進行編碼。 事實上,我對 NavHost 的管理有疑問。 在第一種情況下(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)

而在第二種情況下,我需要在Scaffold可組合項的innerPadding scope 中調用它:

fun MainScreen(navController: NavHostController) {

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

請假設 SetupNavGraph SetupNavGraph() function 按預期工作(調用NavHost生成導航樹)

  • 我嘗試使用兩個NavHost但沒有成功。
  • 如果我在setContent()中設置NavHost ,我就可以加載閃屏並移動到空的BottomNavBar屏幕。 如果我單擊BottomNavElements ,我可以導航到子選項卡(在上面的示例中“收藏夾”、“音樂”、“地點”、“新聞”)但是BottomNavBar消失了
  • 我無法在innerPadding scope 中設置NavHost ,因為它僅在切換到主屏幕后才加載(在上面的示例中“Favorite Tab”+ BottomBarNav)

我發現的唯一解決方法是在每個 BottomNav 子選項卡中生成BottomNavBar可組合項,但這會生成我想避免的可見過渡效果,而且通常這似乎不是一個好的做法。

好的,我找到了解決方案。 這是實現預期結果的步驟:

  1. 創建兩個不同的 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. MainActivity中的setContent()之后初始化NavControllerRootNavGraph 這將負責 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. 在您擁有 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)
    }
}

這會很有魅力! 當然,您需要構建BottomNavBar以管理官方文檔中記錄的導航

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM