web-dev-qa-db-fra.com

Comment donner la même instance de ViewModel au fragment parent et enfant

Il existe deux fragments: ParentFragment et ChildFragment. ChildFragment a été ajouté à une vue de ParentFragment.

Maintenant en utilisant Dagger2 pour Android a le ParentFragmentModule avec une méthode:

@Provides
fun provideViewModel(fragment: ParentFragment, myViewModelFactory: MyViewModelFactory): MyViewModel {
    return ViewModelProviders.of(fragment, myViewModelFactory).get(MyViewModelImpl::class.Java)
}

Où MyViewModelFactory, MyViewModel, MyViewModelImpl sont de simples logiques ViewModel créées dans l'application.

Et le ChildFragmentModule a la méthode:

@Provides
fun provideViewModel(fragment: ChildFragment, myViewModelFactory: MyViewModelFactory): MyViewModel {
    return ViewModelProviders.of(fragment, myViewModelFactory).get(MyViewModelImpl::class.Java)
}

Cela crée évidemment deux instances distinctes de ViewModel car elles reçoivent deux instances de fragment différentes.

Comment pouvons-nous lui faire retourner la même instance afin que les données puissent être partagées entre les fragments parent et enfant?

J'ai essayé de passer le ParentFragment au lieu de ChildFragment dans le ChildFragmentModule, mais cela conduit à une erreur d'injection de dépendance Dagger.

11
mhtmalpani

Créez votre ViewModel avec la portée Activity. Ensuite, tous les Fragment dans cette Activity obtiendront la même instance ViewModel.

Vérifiez officiel ViewModelProviders référence. Vous pouvez créer ViewModel avec la portée Activity et Fragment.

ViewModelProvider of (FragmentActivity activity)

Crée un ViewModelProvider, qui conserve ViewModels pendant qu'une étendue d'activité donnée est en vie. Une explication plus détaillée se trouve dans ViewModel.

et

ViewModelProvider of (Fragment fragment)

Crée un ViewModelProvider, qui conserve ViewModels tant qu'une étendue de fragment donné est vivante. Une explication plus détaillée se trouve dans ViewModel.

Exemple de code pour créer ViewModel

De l'activité:

 movieListViewModel = ViewModelProviders.of(this).get(MovieListViewModel.class);

À partir du fragment:

 movieListViewModel = ViewModelProviders.of(getActivity()).get(MovieListViewModel.class);
19
Abu Yousuf