web-dev-qa-db-fra.com

Problème de ViewPager2 / Tabs avec l'état de ViewModel

Je suis le modèle MVVM - ce qui signifie que j'ai un ViewModel pour chaque fragment.

J'ai ajouté deux onglets en utilisant ViewPager2.

Mon adaptateur ressemble à ceci:

@Override
public Fragment createFragment(int position) {
    switch (position) {
        case 0:
            return new MergedItemsFragment();
        case 1:     
            return new ValidatedMergedItemsFragment();
    }
    return new MergedItemsFragment();
}

Les onglets fonctionnent. Cependant, j'ai remarqué que le ViewModel de mon MergedItemsFragment se comporte bizarrement. Avant d'ajouter des onglets, j'ai navigué vers le fragment comme ceci:

NavHostFragment.findNavController(this).navigate(R.id.action_roomFragment_to_itemsFragment);

Quand je quittais ce fragment avec NavHostFragment.findNavController(this).popBackStack() et plus tard je revenais à ce fragment, j'obtenais un nouveau ViewModel vide. C'était prévu.

Avec la nouvelle approche, je navigue avec return new MergedItemsFragment(). Quand je quitte ce fragment et plus tard au retour, j'obtiens un ViewModel qui contient les anciennes données. C'est un problème car les anciennes données ne sont plus pertinentes car l'utilisateur a sélectionné des données différentes dans un autre fragment.


Mise à jour n ° 1

J'ai réalisé qu'il gardait en fait tous l'ancien Fragments en mémoire parce que les mêmes instructions d'impression sont appelées plusieurs fois. Le temps qu'il est appelé augmente avec le nombre de fois où je pars et reviens à cet écran. Donc, si je pars et reviens 10 fois et tourne mon appareil, il exécutera en fait une ligne 10 fois. Quel est le moyen d'implémenter des onglets/ViewPagers avec des composants de navigation d'une manière qui fonctionne avec ViewModels?


Mise à jour # 2

J'ai défini mes ViewModels comme ceci:

viewModel = new ViewModelProvider(this, providerFactory).get(MergedItemViewModel.class)

J'obtiens les mêmes résultats avec:

viewModel = ViewModelProviders.of(this).get(MergedItemViewModel.class);

Je lie le ViewModel dans le fragment lui-même. Par conséquent, this est le fragment.

9
user123456789
new ViewModelProvider(requireActivity()).get("your_key", YourViewModel.class)

Utilisez requireActivity pour obtenir un ViewModel et non le fragment.

0
boybeak