将活动的ViewModel注入片段的ViewModel中

时间:2018-08-11 16:56:39

标签: android dagger-2 android-architecture-components android-viewmodel dagger

我已经建立了一个与GithubBrowserSample非常相似的项目。因此,匕首的设置是相同的。

请考虑有ActivityViewModelFragmentViewModel,它们具有非零的arg构造函数,因此它们是通过自定义ViewModelProvidersViewModelProvider.Factory获取的。

我想要的是指示匕首在以下代码中注入ActivityViewModel的已创建实例:


    class FragmentViewModel @Inject constructor(
        private val activityViewModel: ActivityViewModel
        private val foo: Foo
    ) : ViewModel() {
        ...
    }

使用当前声明,Dagger将创建ActivityViewModel new 实例,无论已经存在一个实例。

之所以会发生这种情况,是因为存在@Inject的{​​{1}}批注的构造函数。

因此,匕首可以随意假设,这是向ActivityViewModel提供ActivityViewModel实例的正确方法。

我知道如何为普通的Dagger制作东西,但是我不知道如何为Dagger-Android制作东西,这个问题专门针对Dagger-Android设置。

作为一种肮脏的解决方案,我目前正在手动设置该实例:

FragmentViewModel

将父母的 class MyFragment : Fragment { ... override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) viewModel = ViewModelProviders.of(this, viewModelFactory).get(FragmentViewModel::class.java) viewModel.activityViewModel = ViewModelProviders.of(activity!!, viewModelFactory).get(ActivityViewModel::class.java) } ... } 注入孩子的ViewModel的正确方法是什么?

1 个答案:

答案 0 :(得分:0)

这不是对该问题的答案,这是我已经提出并正在使用的一种方法。

已声明以下扩展功能:

inline fun <reified T : ViewModel> Fragment.getViewModel(
    factory: ViewModelProvider.Factory = ViewModelProvider.NewInstanceFactory()
) = ViewModelProviders.of(this, factory).get(T::class.java)

inline fun <reified T : ViewModel> Fragment.getParentViewModel(
    factory: ViewModelProvider.Factory = ViewModelProvider.NewInstanceFactory()
) = ViewModelProviders.of(activity!!, factory).get(T::class.java)

然后在片段类中我们可以声明以下内容:

private val parentViewModel by lazy { getParentViewModel<ParentViewModel>(viewModelFactory) }
private val childViewModel by lazy {
  val field = getViewModel<ChildViewModel>(viewModelFactory)
  field.parentViewModel = parentViewModel
  field
}