Jetpack Compose 嵌套导航和 BottomAppBar

And*_*dra 5 android android-jetpack-navigation android-jetpack-compose

我正在尝试使用 jetpack 撰写导航,但在理解嵌套导航和布局脚手架方面遇到了问题。

\n

我有一个像这样的应用程序屏幕结构

\n
root\n\xe2\x94\x9c\xe2\x94\x80 A\n\xe2\x94\x9c\xe2\x94\x80 B <- Had a bottom navigation bar\n\xe2\x94\x82  \xe2\x94\x9c\xe2\x94\x80 C\n\xe2\x94\x82  \xe2\x94\x9c\xe2\x94\x80 D\n
Run Code Online (Sandbox Code Playgroud)\n

这是粗略的规格

\n
    \n
  • 根位于 MainActivity 中,并具有 NavHost 和脚手架。
  • \n
  • A 和 B 中的应用栏会有所不同。
  • \n
  • B 中会有一个底部导航栏,可用于在 C 和 D 之间导航
  • \n
\n

我一直在浏览文档和 StackOverflow,据我所知,最好将脚手架放在 NavHost 之外。

\n

但是,对于我的情况,如果我无法访问 A 和 B 内的脚手架,如何更新 A 和 B 中的应用程序栏?我只能想到在脚手架中进行分支,如下面的代码

\n
Scaffold(\n    scaffoldState = scaffoldState,\n    topBar = {\n        when {\n            currentDestination?.parent?.route == "Home" -> {\n                TopAppBar(\n                    title = {\n                        Text("Home")\n                    },\n                )\n            }\n            currentDestination?.route == "Other screen" -> {\n                 ....\n            }\n
Run Code Online (Sandbox Code Playgroud)\n

我还需要 A 中的访问脚手架状态。

\n

那么解决此类问题的最佳方法是什么?

\n

Are*_*ref 1

我遇到了这个问题,并且NavHost带有多个嵌套导航Scaffold时遇到了这个问题。

这是我的第一个解决方案:

根有自己的NavHost,包含 2 个独立的页面(A 和 B),这些页面有自己的功能。

如果我们认为页面 A 是像闪屏这样的单页,我们就有一个基本的Scaffold组件。

如果我们认为页面 B 是一种像 Instagram 那样带有底部导航的多页面,那么在顶层我们应该创建一个NavHost为该页面创建一个。

这是我们的根:

sealed class RouteScreen(val route: String) {
    object A : RouteScreen("a")
    object B : RouteScreen("b")
}

@Composable
internal fun RootNavigation(
    modifier: Modifier = Modifier,
    appState: MultiNavigationAppState
) {
    NavHost(
        navController = appState.navController,
        startDestination = RouteScreen.A.route,
        modifier = modifier
    ) {
        addA(appState)
        addB(appState)
    }
}

private fun NavGraphBuilder.addA(
    appState: MultiNavigationAppState
) {
    composable(route = RouteScreen.A.route) {
        AScreen()
    }
}

private fun NavGraphBuilder.addB(
    appState: MultiNavigationAppState
) {
    composable(route = RouteScreen.B.route) {
        BScreen(appState)
    }
}
Run Code Online (Sandbox Code Playgroud)

AScreen是一个你可以使用的可组合项Scaffold在其中使用的可组合项。

BScreen与此相同,AScreen但您可以NavHost为控制选项卡创建另一个。

@Composable
fun BScreen(
    appState: MultiNavigationAppState
) {
    val mainState = rememberMainState()
    Scaffold(
        bottomBar = {...}
    ) {
        BNavigation(...)
    }
}

Run Code Online (Sandbox Code Playgroud)

实际上不建议使用NavHost带有嵌套导航的页面,因为如果页面有选项卡及其类似 Instagram 的功能,我们就会遇到麻烦。

第二个解决方案是我们可以使用 multifragment与自己的NavHost, but it's not all based on Composable 组件一起使用。

正如你提到的,我面临这个问题,你可以通过这个 Github 项目获得更多帮助