如何为一个公共片段创建不同的视图模型?
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()
方法提供 factoryProducer
或 ownerProducer
来完成,但我找不到很多关于它的参考资料,所以我不知道如何实现我的目标.
我终于成功了。
解决方案
首先,我需要继承 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
的枚举。
在我的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?我通过
获取片段的 viewModelval viewModel: MyFragmentViewModel by viewModels()
而且如果我什么都不做,可能三个fragment共享同一个viewModel,这不符合我的要求。我认为这可以通过向 viewModels()
方法提供 factoryProducer
或 ownerProducer
来完成,但我找不到很多关于它的参考资料,所以我不知道如何实现我的目标.
我终于成功了。
解决方案
首先,我需要继承 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
的枚举。