Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ViewModel is created again for the fragment

I create viewmodel in MainFragment:

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

When user select item then navigate to Details fragment, this transaction is added to backstack.

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

When user press back in Details fragment, everything is ok, but if user rotate device in Details fragment and press back then:

  • new instance of ViewModel is created for MainFragment
  • old instance is still alive ( method onCleared not called)

Is this a bug in ViewModelProviders? How to fix this? In my opinion ViewModel should be restored.

like image 853
Adam Miśtal Avatar asked Jun 16 '17 11:06

Adam Miśtal


2 Answers

You are use link to fragment but need to Activity use:

MainViewModel mainViewModel = ViewModelProviders.of(getActivity()).get(MainViewModel.class);
like image 99
Gevork Safaryan Avatar answered Nov 13 '22 10:11

Gevork Safaryan


This is not really obvious, but when you call addToBackStack, the fragment manager will not destroy your fragment, just stops it, when new replace transaction comes. You basically have two items on the backstack now, both being instances of your Details. Since onDestroy was never called for the first one, its ViewModel's onCleared was never called either.

In your case, simply checking if your fragment is currently in the container (e.g. via FragmentManager.findFragment() and NOT replacing it in such situation, should be enough.

like image 41
Michał Klimczak Avatar answered Nov 13 '22 10:11

Michał Klimczak