Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add a fragment to the backstack in MvvmCross 4.0?

I have an Activity which hosts fragments in a frame-layout. If I change the displayed fragment to another, the fragment isn't added to the back-stack and therefore the use of the "Back"-button will immeditately close the app instead of navigating back (FragmentManager.BackStackEntryCount is always 0 in the OnBackPressed()-callback).

In the ViewModel of the "MainActivity" that hosts the fragments I show the fragment via the ShowViewModel<>-method:

public class MainViewModel : MvxViewModel
{
    public IMvxCommand ShowHomeCommand
    {
        get { return new MvxCommand(ShowHomeExecuted); }
    }

    private void ShowHomeExecuted()
    {
        ShowViewModel<HomeViewModel>();
    }
}

The fragment-class has an annotation to assign the ViewModel to a host-activity:

[MvxFragment(typeof(MainViewModel), Resource.Id.fragment_container)]
[Register("namespace.of.HomeFragment")]

I use the default AndroidViewPresenter in my Setup-class:

protected override IMvxAndroidViewPresenter CreateViewPresenter()
{
   var mvxFragmentsPresenter = new MvxFragmentsPresenter(AndroidViewAssemblies);
   Mvx.RegisterSingleton<IMvxAndroidViewPresenter>(mvxFragmentsPresenter);
   return mvxFragmentsPresenter;
}

I expected a parameter "AddToBackstack" or similar in the MvxFragment-Attribut or in the MvxFragment-class but there is nothing like this. Do I miss something or is there currently no support for the back-stack in the new fragment-mechanism in MvvmCross 4.0?

like image 396
Stefan Wanitzek Avatar asked Mar 20 '16 13:03

Stefan Wanitzek


People also ask

What is add to Backstack?

Calling addToBackStack() commits the transaction to the back stack. The user can later reverse the transaction and bring back the previous fragment by pressing the Back button. If you added or removed multiple fragments within a single transaction, all of those operations are undone when the back stack is popped.

How do you resume an existing Backstack fragment?

Since you want only one back stack entry per Fragment , make the back state name the Fragment's class name (via getClass(). getName() ). Then when replacing a Fragment , use the popBackStackImmediate() method. If it returns true, it means there is an instance of the Fragment in the back stack.

How do I delete all fragments in Backstack?

Explanation: MainFragment -> Fragment A -> Fragment B (this is added to backstack) -> Fragment C -> MainFragment (clear backstack ).


Video Answer


2 Answers

What you can do is add something like this to your MainActivity:

public override void OnBeforeFragmentChanging (IMvxCachedFragmentInfo fragmentInfo, Android.Support.V4.App.FragmentTransaction transaction)
        {
            var currentFrag = SupportFragmentManager.FindFragmentById (Resource.Id.content_frame) as MvxFragment;

            if(currentFrag != null 
                && fragmentInfo.ViewModelType != typeof(MenuViewModel) 
                && currentFrag.FindAssociatedViewModelType() != fragmentInfo.ViewModelType)
                fragmentInfo.AddToBackStack = true;
            base.OnBeforeFragmentChanging (fragmentInfo, transaction);
        }

This will add the fragment to the backstack before the navigation happens.

like image 192
Martijn00 Avatar answered Oct 16 '22 16:10

Martijn00


I think it is as simple as changing the attributes on your fragment to

[MvxFragment(typeof(MainViewModel), Resource.Id.fragment_container, AddToBackStack = true)]
[Register("namespace.of.HomeFragment")]

This certainly works in v4.2.3

like image 21
rideintothesun Avatar answered Oct 16 '22 15:10

rideintothesun