如何为一个公共片段创建不同的视图模型?

How to create different viewModels for a common fragment?

在我的Android应用中,有三个布局和功能相似的片段,只是fetcher参数不同。简而言之,可以定义为

class MyFragment(private val fetcher: /* fetcher type */) : Fragment() {
    // Somme implementations
}

class MyFragmentViewModel(private val fetcher: /* fetcher type */) : ViewModel() {
    // ViewModel implementations
}

要创建这三个片段,我只需将三个不同的 fetcher 传递给 MyFragment 并且 MyFragment 需要将 fetcher 传递给它的 viewModel。

我的问题是,如何让三个片段有自己的viewModel?我通过

获取片段的 viewModel
val viewModel: MyFragmentViewModel by viewModels()

而且如果我什么都不做,可能三个fragment共享同一个viewModel,这不符合我的要求。我认为这可以通过向 viewModels() 方法提供 factoryProducerownerProducer 来完成,但我找不到很多关于它的参考资料,所以我不知道如何实现我的目标.

我终于成功了。

解决方案

首先,我需要继承 ViewModelProvider.Factory:

class MyFragmentViewModelFactory(private val fetcher: /* fetcher type */) : ViewModelProvider.Factory {
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        return MyFragmentViewModel(this.fetcher) as T
    }
}

然后在我的片段中使用 viewModel:

val viewModel: MyFragmentViewModel by viewModels {
    NyFragmentViewModelFactory(fetcher)
}

其他

要在这种情况下使用导航框架,只需删除 MyFragment 中的 fetcher 参数,并使用 SafeArgs 传递解析为不同 fetcher 的枚举。