【问题标题】:Inject viewModel to @Composable将 viewModel 注入@Composable
【发布时间】:2021-05-16 16:40:10
【问题描述】:

我的 ProfileScreen 有 viewModel。

@Composable
fun ProfileScreen() {
    val viewModel: ProfileViewModel = viewModel()
    ...
}

每次调用 ProfileScreen 时,都会创建新的 viewModel。我怎样才能为我的 ProfileScreen 创建一个 viewModel 实例。我试图在https://insert-koin.io/docs/reference/koin-android/compose/ 之后注入 viewModel 但是当我尝试时

val viewModel: ProfileViewModel = viewModel()

Android Studio 抛出错误。

【问题讨论】:

    标签: android kotlin dependency-injection android-jetpack-compose koin


    【解决方案1】:

    或者使用remember()在recompose调用之间保存实例ViewModel

    @Composable
    fun ProfileScreen() {
        val viewModel = remember { ProfileViewModel() }
        ...
    }
    

    另外,rememberSaveable 允许在重新创建活动之间保存状态(又名数据类)

    【讨论】:

    • 当我尝试它时,我得到错误来自记忆{}:记住调用不能返回单位,类型不匹配。必需:ProfileViewModel 找到:单位 我应该在某个地方定义我的 ProfileViewModel() 类吗?
    • 通过调用记住它会在重组后继续存在,但如果设备方向发生变化则不会。它将像一个在当前组合中记住的普通类,而不像典型的 android viewModel。
    • remember 如果 ProfileScreen 在后台堆栈中(使用 Compose Navigation 或 Fragments 时)或任何其他配置更改(如分屏、暗模式切换等),也将无法生存,而不仅仅是方向变化。
    • 这是一个糟糕的模式
    【解决方案2】:

    您的 viewModel 会在您销毁可组合组件时被销毁,它可以在重新组合中存活,但一旦您的可组合组件被销毁,它就会被销毁。

    您可以做的是在比 ProfileScreen 可组合的寿命更长的范围内创建 viewModel,然后将 viewModel 作为参数传递给它。

    这样的事情应该可以工作。

    @Composable 
    fun MainScreen() {
         val vModel : ProfileViewModel = viewModel()
         ....
         ProfileScreen(vModel)
    }
    

    【讨论】:

      【解决方案3】:

      如果您想使用 Koin 将您的视图模型注入可组合,您应该遵循文档中的描述。

      getViewModel() - fetch instance
      

      通过调用该方法,Koin 将搜索该视图模型并提供一个实例。

      这是在我的应用程序中注入视图模型的示例。

      fun ManualControlScreen(
        onDrawerClick: () -> Unit,
        viewModel: ManualControlViewModel = getViewModel<ManualControlViewModel>()
      ) {
         // Your composable UI
      }
      

      【讨论】:

        猜你喜欢
        • 2023-01-09
        • 2021-04-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-26
        • 2021-02-23
        相关资源
        最近更新 更多