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?
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.
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.
Explanation: MainFragment -> Fragment A -> Fragment B (this is added to backstack) -> Fragment C -> MainFragment (clear backstack ).
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With