导航后清除整个返回堆栈

Clearing the entire back stack after navigation

有没有办法在导航到特定 ViewModel 后清除整个导航堆栈(包括 ViewModel 和视图)?在这种情况下,我需要在用户注销时销毁导航堆栈。据我了解,MvxPopToRootPresentationHint 只有在 LoginViewModel 首先位于导航堆栈的根部时才有用。

我还应该提到,我在 Android 上的堆栈同时包含活动和片段,我最终需要导航到片段(因此在这里使用带有 CLEAR_TOP 的意图很困难):

InterstitialContainerViewModel (NoHistory = true on Activity)
InterstitialViewModel
      ↓
LoginContainerViewModel (NoHistory = true on Activity)
LoginViewModel
      ↓
MainContainerViewModel
MainViewModel && MenuViewModel
                       ↓
                   LogoutAsync
                       ↓
Should give me a new instance of LoginContainerViewModel/LoginViewModel 
with no other ViewModels, Activities, or Fragments in the stack

理想情况下,我想在共享代码中独立于平台执行此操作,但如果实现此流程需要自定义演示代码,那也没关系。

这可能不是实现此目的的最干净的方法,但它似乎可行:

1.创建一个 MvxPresentationHint(在共享代码中):

public class LogoutPresentationHint : MvxPresentationHint
{
}

2。创建一个覆盖 ChangePresentation:

的自定义演示者
internal class MyPresenter : MvxAppCompatViewPresenter
{
    public MyPresenter(IEnumerable<Assembly> androidViewAssemblies)
        : base(androidViewAssemblies)
    {
    }

    public override Task<bool> ChangePresentation(MvxPresentationHint hint)
    {
        if (hint is LogoutPresentationHint)
        {
            var intent = new Intent(CurrentActivity, typeof(LoginContainerActivity));
            intent.AddFlags(ActivityFlags.ClearTop | ActivityFlags.NewTask);
            ShowIntent(intent, new Bundle());
            CurrentActivity.Finish();
            Show(new MvxViewModelRequest(typeof(LoginViewModel)));
        }

        return base.ChangePresentation(hint);
    }
}

3。在 Setup.cs:

中使用自定义演示者
protected override IMvxAndroidViewPresenter CreateViewPresenter()
    => new MyPresenter(AndroidViewAssemblies);

4.覆盖 LoginContainerActivity 中的 OnBackPressed 以在用户按下后退时最小化应用程序:

public override void OnBackPressed()
{
    Minimise();
}

private void Minimise()
{
    var minimiseIntent = new Intent(Intent.ActionMain);
    minimiseIntent.AddCategory(Intent.CategoryHome);
    minimiseIntent.SetFlags(ActivityFlags.NewTask);
    StartActivity(minimiseIntent);
}

5.在 LogoutAsync:

中使用新的 MvxPresentationHint 导航
private async Task LogoutAsync()
    => await NavigationService.ChangePresentation(new LogoutPresentationHint());

这几乎完美。整个返回堆栈被删除,登录 ViewModels 的新实例和 Activities/Fragments 被创建并正确呈现。我发现的唯一警告是,如果用户按回键(然后最小化应用程序)然后从最近重新打开应用程序,它会重新打开容器 activity 而没有片段。在演示者中仅引发 ActivityLifetimeListener_ActivityChanged 方法。也许可以连接到该方法并在那时正确呈现片段,但我还没有设法做到这一点。