MvvmCross / MvvmCross-AndroidSupport

Android support library packages for MvvmCross: The .NET MVVM framework for cross-platform solutions.
http://mvvmcross.com
15 stars 0 forks source link

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

Closed duartem2u closed 8 years ago

duartem2u commented 8 years ago

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 commented 8 years ago

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