android - Jetpack 撰写和导航 : Problems share ViewModel in nested graph

标签 android android-jetpack-compose dagger-hilt android-jetpack-navigation

据此example我在嵌套导航图中实现了共享 View 模型。
设置
嵌套图:

private fun NavGraphBuilder.accountGraph(navController: NavHostController) {
   navigation(
      startDestination = "main",
      route = "account") {

       composable("main") {
          val vm = hiltViewModel<AccountViewModel(navController.getBackStackEntry("account"))
          //... ui ...
       }

       composable("login") {
          val vm = hiltViewModel<AccountViewModel(navController.getBackStackEntry("account"))
          //... ui ...
       }
   }
}
导航主机:
@Composable
private fun NavHost(navController: NavHostController, modifier: Modifier = Modifier){
   NavHost(
      navController = navController,
      startDestination = MainScreen.Home.route,
      modifier = modifier
   ) {
      composable("home") { HomeScreen(hiltViewModel()) }
      composable("otherRoute") { OtherScreen(hiltViewModel()) }
      accountGraph(navController)
   }
}
底部导航栏:
@Composable
private fun ButtonNav(navController: NavHostController) {
   BottomNavigation {
      val navBackStackEntry by navController.currentBackStackEntryAsState()
      val currentDestination = navBackStackEntry?.destination

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

                  // Pop up to the start destination of the graph to
                  // avoid building up a large stack of destinations
                  // on the back stack as users select items
                  navController.graph.startDestinationRoute?.let { route ->
                     popUpTo(route) { saveState = true }
                  }

                  // Avoid multiple copies of the same destination when
                  // re-selecting the same item
                  launchSingleTop = true

                  // Restore state when re-selecting a previously selected item
                  restoreState = true
               }
            }
         )
      }
   }
}
问题
使用此设置,如果我导航到“帐户”(嵌套图)并返回到任何其他路线,我会收到错误消息:
java.lang.IllegalArgumentException: No destination with route account is on the NavController's back stack. The current destination is Destination(0x78dd8526) route=otherRoute
假设/研究结果
底部导航项
删除 popUpTo(route) 时未发生异常点击。但后来我得到了一大堆。
backStackEntry 的生命周期
看看以下内容:
//...
composable("main") { backStackEntry ->
   val vm = hiltViewModel<AccountViewModel(navController.getBackStackEntry("account"))
   //... ui ...
}
//...
我发现当导航回来时,将被重新组合的组合将被重新组合,但在这种情况下,backStackEntry 接缝有另一个 lifecycle.currentState因为如果我像这样包装整个可组合:
//...
composable("main") { backStackEntry ->
  if(backStackEntry.lifecycle.currentState == Lifecycle.State.RESUMED){
     val vm = hiltViewModel<AccountViewModel(navController.getBackStackEntry("account"))
     //... ui ...
  }
}
//...
...没有发生异常。
当我看到官方示例有 similar workarounds 时,我想到了生命周期问题的想法。到位。
概括
我实际上不知道我是否做错了什么,或者我是否在这里错过了一个概念。我可以将生命周期检查解决方法落实到位,但这真的符合预期吗?除此之外,我在文档中没有找到任何关于此的提示。
有谁知道如何以正确的方式解决这个问题?
问候,
克里斯

最佳答案

有一个 issue与导航组件。它已使用 v2.4.0-alpha08 为我修复

关于android - Jetpack 撰写和导航 : Problems share ViewModel in nested graph,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68738304/

相关文章:

android - 过滤 ListView 并获得正确的 onclick 项目

android - 如何在 Compose 中预加载线圈图像?

android - 如何使用 Dagger-Hilt 注入(inject) Kotlin 扩展属性

android - 如何使用 Hilt 绑定(bind)/提供 Activity 或 Fragment?

android - 在 Android 上渲染 Maya 动画?

android - 使用 MediaCodec 和 MTK Codec 编码时选择 H264 Profile

android - onServiceConnected 是否仅在 Service onCreate 之后调用?

android - 什么是脚手架?喷气背包组成

android - 使用 AnnotatedString 在文本之间添加小填充/边距

android - 创建 Hilt viewModel 时出错