Skip to content
This repository has been archived by the owner. It is now read-only.

The VM lifecycle methods aren't called when showing fragments hosted by distinct activities #303

Closed
duartem2u opened this issue Oct 13, 2016 · 1 comment

Comments

@duartem2u
Copy link

Steps to reproduce

  1. Create an app with a MvxFragment Fragment1 hosted by a MvxCachingFragmentCompatActivity Activity1, and a MvxFragment Fragment2 hosted by a MvxCachingFragmentCompatActivity Activity2. The fragments must have the MvxFragmentAttribute:
[MvxFragment(typeof(Activity1), Resource.Id.content_frame, true)]
[Register("example.droid.fragments.Fragment1")]
public class Fragment1 : MvxFragment<Fragment1ViewModel>
[MvxFragment(typeof(Activity2), Resource.Id.content_frame, true)]
[Register("example.droid.fragments.Fragment2")]
public class Fragment2 : MvxFragment<Fragment2ViewModel>
  1. In the Fragment1 VM, create a command to navigate to Fragment2, using ShowViewModel<Fragment2ViewModel>(). In the Fragment2 VM, create a command to navigate to Fragment1, using ShowViewModel<Fragment1ViewModel>().
  2. Do the following navigation:
    i. open the app. The Fragment1ViewModel is shown
    ii. click the button to show Fragment2ViewModel.
    iii. when Fragment2ViewModel is shown, the lifecycle methods (Init, Start, etc) are called.
    iv. click the button in Fragment2ViewModel to show Fragment1ViewModel again.
    v. when Fragment1ViewModel is shown again, the lifecycle methods aren't called. If the steps ii through iv are repeated, the lifecycle methods of each VM aren't called again.

Expected behavior

The VM lifecycle methods (Init, Start, etc) should be called when the fragments are shown

Actual behavior

The ViewModel lifecycle methods aren't called.

Origin of the issue

From what I've seen, it seems to me that this is happening because the lifecycle methods aren't called when a cached VM is found in the OnCreate method of MvxFragmentExtensions. The lines of code in question are these:

var cache = Mvx.Resolve<IMvxMultipleViewModelCache>();
var cached = cache.GetAndClear(viewModelType, fragmentView.UniqueImmutableCacheTag);

view.OnViewCreate(() => cached ?? LoadViewModel(fragmentView, bundle, fragment.Activity.GetType(), request));

Should something like this be done instead?

var cache = Mvx.Resolve<IMvxMultipleViewModelCache>();
var cached = cache.GetAndClear(viewModelType, fragmentView.UniqueImmutableCacheTag);

view.OnViewCreate(() =>
{
    if (cached != null)
    {
        RunViewModelLifecycle(cached, bundle, request);
        return cached;
    }

    return LoadViewModel(fragmentView, bundle, fragment.Activity.GetType(), request);
});

I've forked the MvvmCross-AndroidSupport repository and made some changes to the sample that exemplify the behavior described in this issue. The only difference is that the navigation is done using the DrawerLayout instead of buttons on each fragment, but I believe this doesn't influence the issue. You can find my fork here.

@duartem2u
Copy link
Author

Closing this because there already is an open issue (#194) describing this problem. My mistake.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

No branches or pull requests

1 participant