2017-06-16 2 views
1

je crée viewmodel dans MainFragment:ViewModel est créé à nouveau pour le fragment

@Override 
public void onActivityCreated(@Nullable Bundle savedInstanceState) { 
    super.onActivityCreated(savedInstanceState); 
    ... 
    MainViewModel mainViewModel = ViewModelProviders.of(this).get(MainViewModel.class); 
    ... 
} 

Lorsque l'utilisateur sélectionner un élément puis accédez au fragment Détails, cette opération est ajoutée à backstack.

getFragmentManager() 
       .beginTransaction() 
       .replace(R.id.root, Details.newInstance()) 
       .addToBackStack(null) 
       .commit(); 

Lorsque l'utilisateur appuie sur retour dans le fragment Détails, tout est ok, mais si l'utilisateur tourne dispositif dans le fragment Détails et appuyez à l'époque:

  • nouvelle instance de ViewModel est créé pour MainFragment
  • vieux par exemple est encore en vie (méthode onCleared pas appelée)

est-ce un bogue dans ViewModelProviders? Comment régler ceci? À mon avis ViewModel devrait être restauré.

+0

Avez-vous trouvé une solution à cela? – SqueezyMo

Répondre

-1

Vous êtes lien utilisé pour fragmenter mais ont besoin d'utiliser d'activité:

MainViewModel mainViewModel = ViewModelProviders.of(getActivity()).get(MainViewModel.class); 
+1

C'est une mauvaise idée Si je fais cela, chaque ViewModel va vivre aussi longtemps que l'activité.Je ne veux pas.Je veux ViewModel vivre aussi longtemps que le fragment –

+0

dans quelle méthode vous ajoutez le fragment? –

+0

Je replece fragments dans le rappel lorsque l'utilisateur sélectionnez item dans recyclerview –

1

Ce n'est pas vraiment évident, mais quand vous appelez addToBackStack, le gestionnaire de fragment ne détruira pas votre fragment, juste l'arrête, lorsque de nouvelles replace transaction vient. Vous avez essentiellement deux éléments sur le backstack maintenant, les deux étant des instances de votre Details. Puisque onDestroy n'a jamais été appelé pour le premier, son ViewModel'sonCleared n'a jamais été appelé non plus.

Dans votre cas, simplement pour vérifier si votre fragment est actuellement dans le récipient (par exemple par l'intermédiaire FragmentManager.findFragment() sans le remplacer dans une telle situation, devrait être suffisant.