首页 > 解决方案 > 如何正确使用 viewModel 和组合导航?

问题描述

在使用Di的情况下,Android官网上的写法如下

// import androidx.hilt.navigation.compose.hiltViewModel

@Composable
fun MyApp() {
    NavHost(navController, startDestination = startRoute) {
        composable("example") { backStackEntry ->
            // Creates a ViewModel from the current BackStackEntry
            // Available in the androidx.hilt:hilt-navigation-compose artifact
            val exampleViewModel = hiltViewModel<ExampleViewModel>()
            ExampleScreen(exampleViewModel)
        }
        /* ... */
    }
}

那么如果ExampleScreen中还有很多其他的@Composable功能,像这样

ExampleScreen() {
  A()
  B()
}
A() {
  TopBar()
  BottomBar()
  ....
}
B() ...

如果A()和它的子函数都需要用到vm里面的东西,那不就得一一传递vm参数了吗?因为如果在这些函数中创建了vm,就不是单例了(因为navigation compose会影响viewModel,每次切换页面,这些viewModel都会重新创建为一个新的)。疑惑的时候,又在官网上看到了这个设计思路:

传递显式参数

一般的想法是我应该在父函数中传递子函数的逻辑代码,例如在ExampleScreen中写:

ExampleScreen() {
  val vm = hilt<VM>()
  A(onClick = vm.onClick, ...)
  B(...)
}

所以我的问题是,如果我有很多嵌套的函数,难道我不需要在每个函数中写一个逻辑参数吗?那么如果我想在每个函数中直接创建一个vm,但是又不是singleton,该怎么办呢?我很困惑

标签: androiddependency-injectionandroid-jetpackandroid-jetpack-composedagger-hilt

解决方案


通过在顶层注入视图模型,您已经做了正确的事情。现在由您决定如何传递它。它们最终只是功能。您可以在任何地方传递视图模型,仅传递特定成员或不传递任何内容。

做有意义的事,如果它不起作用,则进行迭代。


推荐阅读