使用 Hilt 进行依赖注入时,android compose 项目中的共享视图模型?

Ali*_*waz 9 viewmodel android-mvvm android-jetpack-compose

任何人都知道如何在不同的可组合项之间保留共享视图模型对象?我正在使用 hilt 并在可组合项中使用 hilt 注入视图模型实例。基本上有 3 个屏幕共享相同的数据和更改,我想共享它,并且我正在考虑通过共享视图模型共享这些数据。

myViewModel: MyViewModel = hiltViewModel()
Run Code Online (Sandbox Code Playgroud)

那么我如何使用这个 MyViewModel 作为共享视图模型?

Ali*_*waz 10

您所需要的只是像这样在导航返回堆栈条目中找到视图模型并将其传递到下一个可组合屏幕:

val backStackEntry = remember {
    navHostController.getBackStackEntry("first_screen_route_where_viewmodel_was_firstly_initialized")
}
val viewModel: MyViewModel = hiltViewModel(backStackEntry)
Run Code Online (Sandbox Code Playgroud)

现在您已经获得了视图模型,它与您在之前的屏幕中保留的状态完全相同。现在您可以将其用作共享视图模型。感谢@Pylyp 的指导..

  • 请注意,“记住 {navController.getBackStackEntry(parentId)}” 可能会导致崩溃,并且现在会触发 lint 警告([此处有更多信息](https://issuetracker.google.com/issues/227382831))。解决方案是使用一个`backStackEntry`作为`remember`之类的键。`记住(navBackStackEntry){navController.getBackStackEntry(parentId)}` (2认同)

Gáb*_*áth 5

根据官方文档

如果您需要检索范围为导航路线或导航图的 ViewModel 实例,请使用 hiltViewModel 可组合函数并将相应的 backStackEntry 作为参数传递:

import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.compose.getBackStackEntry

@Composable
fun MyApp() {
    NavHost(navController, startDestination = startRoute) {
        navigation(startDestination = innerStartRoute, route = "Parent") {
            // ...
            composable("exampleWithRoute") { backStackEntry ->
                val parentEntry = remember(backStackEntry) {
                    navController.getBackStackEntry("Parent")
                }
                val parentViewModel = hiltViewModel<ParentViewModel>(parentEntry)
                ExampleWithRouteScreen(parentViewModel)
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)