首页 > 解决方案 > 在 Jetpack Compose -> Composable 函数中使用输入参数启动 ViewModel

问题描述

我有一个将字符串作为参数的 ViewModel

class ComplimentIdeasViewModel(ideaCategory : String) : ViewModel()  {
    //some code here
}

在不使用 ViewModel 工厂和 Hilt 的情况下,在可组合的乐趣中启动此 ViewModel 的最佳方式是什么?一个简单的语句似乎在可组合的乐趣中实现了这一点

@Composable
fun SampleComposableFun() {
    val compIdeasViewModel = remember { ComplimentIdeasViewModel("someCategory") }
}

当我尝试这样做时,Android Studio 中没有任何警告,但这似乎太容易实现了,我可以在没有依赖注入和 ViewModelFactory 类的情况下做到这一点。我在这里错过了什么吗?

标签: androidandroid-jetpackandroid-viewmodelandroid-jetpack-composeandroid-mvvm

解决方案


CompositionLocal您的ViewModel.

val YourViewModel = compositionLocalOf { YourViewModel(...) }

然后初始化它(你可能会在ViewModelProvider.Factory这里使用)。然后将其提供给您的应用程序。

CompositionLocalProvider(
  YourViewModel provides yourInitialisedViewModel,
) {
  YourApp()
}

然后在可组合中引用它。

@Composable
fun SampleComposableFun(
  compIdeasViewModel = YourViewModel.current
) {
  ... 
}

请注意,文档说ViewModels 不适合CompositionLocals,因为它们会使您的可组合项更难测试,使您的可组合项与此应用程序绑定并使其更难使用@Preview

有些人对此非常生气。但是,如果您设法模拟出ViewModel,那么您可以测试应用程序并使用@Preview,并且您的可组合项与应用程序相关联而不是通用的,那么我认为没有问题。

您可以相当简单地模拟一个ViewModel,只要它的依赖项作为参数包含在内(无论如何这是一个好习惯)。

open class MockedViewModel : MyViewModel(
  app = Application(),
  someOtherDependeny = MockedDependecy(),
)

您的依赖ViewModel项越多,您需要做的模拟就越多。但我并没有发现它令人望而却步,并且将其ViewModel作为默认参数极大地加快了开发速度。


推荐阅读