如何将同一个ViewModel实例同时提供给Parent和Child片段

mht*_*ani 11 android dependency-injection mvvm dagger android-viewmodel

有两个片段:ParentFragment和ChildFragment. ChildFragment已被添加到视图中ParentFragment.

现在使用Dagger2Android有ParentFragmentModule一个方法:

@Provides
fun provideViewModel(fragment: ParentFragment, myViewModelFactory: MyViewModelFactory): MyViewModel {
    return ViewModelProviders.of(fragment, myViewModelFactory).get(MyViewModelImpl::class.java)
}
Run Code Online (Sandbox Code Playgroud)

其中MyViewModelFactory,MyViewModel,MyViewModelImpl是在应用程序中创建的简单ViewModel逻辑.

并且ChildFragmentModule具有以下方法:

@Provides
fun provideViewModel(fragment: ChildFragment, myViewModelFactory: MyViewModelFactory): MyViewModel {
    return ViewModelProviders.of(fragment, myViewModelFactory).get(MyViewModelImpl::class.java)
}
Run Code Online (Sandbox Code Playgroud)

这显然是创建两个单独的实例,ViewModel因为它们接收两个不同的片段实例.

我们如何使它返回相同的实例,以便可以在Parent和Child片段之间共享数据?

我试过传递ParentFragment而不是ChildFragmentChildFragmentModule,但这导致Dagger依赖注入错误.

Abu*_*suf 20

创建您ViewModelActivity范围.然后,所有FragmentActivity会得到相同的ViewModel实例.

查看官方ViewModelProviders参考.您可以ViewModel使用both ActivityFragmentscope 创建.

ViewModelProvider of (FragmentActivity activity)
Run Code Online (Sandbox Code Playgroud)

创建一个ViewModelProvider,它在给定Activity的作用域存活时保留ViewModels.更详细的解释在ViewModel中.

ViewModelProvider of (Fragment fragment)
Run Code Online (Sandbox Code Playgroud)

创建一个ViewModelProvider,它在给定片段的作用域存活时保留ViewModels.更详细的解释在ViewModel中.

用于创建的示例代码 ViewModel

来自活动:

 movieListViewModel = ViewModelProviders.of(this).get(MovieListViewModel.class);
Run Code Online (Sandbox Code Playgroud)

来自片段:

 movieListViewModel = ViewModelProviders.of(getActivity()).get(MovieListViewModel.class);
Run Code Online (Sandbox Code Playgroud)

  • 单一活动方法怎么样?保持链接到一个活动的所有共享视图模型并不好. (7认同)
  • 谢谢.这很顺利!仅仅为了知识,父和子片段范围同时存在.如何在不使用Activity的情况下实现相同的功能? (4认同)

Alo*_*hra 14

使用Fragment-ktx我们可以这样做In **ParentFragment**

 private val viewModel: DemoViewModel by viewModels()
Run Code Online (Sandbox Code Playgroud)

In ChildFragment

 private val viewModel: DemoViewModel by viewModels(
    ownerProducer = { requireParentFragment() }
)
Run Code Online (Sandbox Code Playgroud)

这样做我们可以在Parent FragmentChildFragment 中获得相同的ViewModel实例

应用程序中添加依赖项-> build.gralde

implementation 'androidx.fragment:fragment-ktx:1.1.0
Run Code Online (Sandbox Code Playgroud)