web-dev-qa-db-fra.com

Android MVVM: Activité avec plusieurs fragments - Où mettre les LiveData partagées?

J'ai une question architecturale sur les Android ViewModels:

Disons que dans mon application, j'ai une activité avec deux fragments à l'intérieur (à l'aide d'un Viewpager). Les deux fragments font des choses différentes (ils peuvent donc avoir leur propre ViewModel?), Mais ils ont également besoin de différentes données similaires.

Il s'agit par exemple de l'état si une connexion réseau est disponible ou non (et les deux fragments affichent des interfaces utilisateur d'erreur différentes s'il n'y a pas de connexion), ou d'un paramètre utilisateur qui provient d'un Push à partir d'un serveur et affecte les deux fragments de manière égale.

Cela ressemble à ceci:

enter image description here

Maintenant, ma question est de savoir comment gérer cette situation lors de l'utilisation de ViewModels? Est-il bon qu'une vue observe plusieurs ViewModels, comme ce serait le cas si j'avais un ViewModel pour l'activité (contenant l'état dont les deux ont également besoin) et un pour chaque fragment, comme ceci:

enter image description here

Cela a été suggéré ici par exemple, mais ce n'est pas une bonne pratique, car la relation dans MVVM est généralement

Afficher n - 1 Afficher le modèle n - 1 Modèle

Mais je ne sais pas où est le bon endroit pour de telles LiveData partagées dans mon cas?

28
stamanuel

Je pense que le concept derrière le ViewModel était qu'il est censé être lié à un seul " écran " plutôt qu'à un " Voir ". Donc, selon cette logique, je pense que vous pouvez utiliser le même ViewModel si plusieurs fragments font référence au même ViewModel car ils appartiennent techniquement au même " Screen ".

Dans les fragments, vous pouvez demander l'activité du ViewModel qui contient l'instance de LiveData et vous fournir les mises à jour selon les besoins.

J'espère que ça répond à ta question.

Mise à jour: j'ai trouvé n lien vers un exemple de fragment dans les exemples Google . Découvrez la méthode onCreateView (). Coller le code ci-dessous pour référence:

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    final View root = inflater.inflate(R.layout.addtask_frag, container, false);
    if (mViewDataBinding == null) {
        mViewDataBinding = AddtaskFragBinding.bind(root);
    }

    mViewModel = AddEditTaskActivity.obtainViewModel(getActivity());

    mViewDataBinding.setViewmodel(mViewModel);

    setHasOptionsMenu(true);
    setRetainInstance(false);

    return mViewDataBinding.getRoot();
}

P.S. Si vous avez trouvé une meilleure solution/réponse/pratique, laissez-moi le savoir.

9
karthik prasad