Xamarin MvvmCross Android Prevent Back Button reverts to previous view

I am trying to create a neat solution for the following situation:

I created an application that requires credentials for user authentication. Whenever the API wants to re-authenticate a user, I would like to force the user to return to the login view. This functionality works great, but when the user clicks the back button on the device, the previous view is displayed. I would like to see that when the user clicks the back button, the application exits.

MvvmCross has the ability to use the MvxPresentationHint . I created CustomAndroidViewPresenter and created the following MvxAndroidSetup:

public class Setup : MvxAndroidSetup { private CustomAndroidViewPresenter _presenter; public Setup(Context applicationContext) : base(applicationContext) { _presenter = new CustomAndroidViewPresenter(applicationContext); } protected override IMvxAndroidViewPresenter CreateViewPresenter() { Mvx.RegisterSingleton(_presenter); return _presenter; } } 

I know you should call Finish (); at an event to prevent it from tipping back to an unverified name. But listing applicationContext throws an exception.

 public CustomAndroidViewPresenter(Context context) { _context = context; } public override void ChangePresentation(MvxPresentationHint hint) { if (hint is LoginOnlyBackStackHint) { var context = Application.Context; if (context is Activity) { // Context is NOT activity } try { Activity x = (Activity) context; x.Finish(); // Exception is thrown } catch (Exception ex) { } } base.ChangePresentation(hint); } 

Does anyone have any ideas how to achieve this?

Thank you very much in advance.

+5
source share
2 answers

I had the same problem. Just run a custom presenter that sets some flags of intent if you want to achieve this:

 public class CustomAndroidPresenter : MvxAndroidViewPresenter { public override void Show(MvxViewModelRequest request) { if (request != null && request.PresentationValues != null) { if (request.PresentationValues.ContainsKey("MyCustomFlag")) { // Get intent from request and set flags to clear backstack. var intent = base.CreateIntentForRequest(request); intent.SetFlags(ActivityFlags.ClearTask | ActivityFlags.NewTask); base.Show(intent); return; } } base.Show(request); } } 

Then you need to set this leading to your settings class:

 protected override IMvxAndroidViewPresenter CreateViewPresenter() { var presenter = new CustomAndroidPresenter(); Mvx.RegisterSingleton<IMvxViewPresenter>(presenter); return presenter; } 

And then, to show the viewmodel (for example, your login-view), simply set your key-code-key, which the host knows that he must set inten-flags:

 protected void ShowViewModel<TViewModel>(bool clearbackstack) where TViewModel : MvxViewModel { if (clearbackstack) { var presentationBundle = new MvxBundle(new Dictionary<string, string> { { "MyCustomFlag", "" } }); ShowViewModel<TViewModel>(presentationBundle: presentationBundle); return; } // Normal start ShowViewModel<TViewModel>(); } 

To show the view mode (without reverse navigation), simply use the following code:

 ShowViewModel<MyViewModel>(true); 

And then, when you click the "Back" button, you cannot return to the previous action, since the stop memory will be deleted.

+11
source

You can use the Activity OnStop lifecycle method.

 public class LoginActivity : MvxAppCompatActivity<LoginViewModel> { protected override void OnCreate(Bundle bundle) { base.OnCreate(bundle); SetContentView(Resource.Layout.activity_login); } /// <summary> /// Removes activity from history after navigating to new activity. /// </summary> protected override void OnStop() { base.OnStop(); Finish(); } /// <summary> /// Closes app if back button is pressed. /// </summary> public override void OnBackPressed() { if (FragmentManager.BackStackEntryCount > 0) { FragmentManager.PopBackStack(); } else { base.OnBackPressed(); } } } 
+1
source

Source: https://habr.com/ru/post/1215213/


All Articles