【问题标题】:Clearing the entire back stack after navigation导航后清除整个后台堆栈
【发布时间】:2019-12-23 13:33:56
【问题描述】:

有没有办法在导航到特定的 ViewModel 后清除整个导航堆栈(ViewModel 和 View)?在这种情况下,我需要在用户注销时销毁导航堆栈。据我了解,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

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

【问题讨论】:

    标签: mvvmcross


    【解决方案1】:

    这可能不是实现这一目标的最干净的方法,但它似乎有效:

    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());
    

    这几乎可以完美运行。整个后台堆栈被删除,登录视图模型和活动/片段的新实例被创建并正确显示。我发现的唯一警告是,如果用户按下(然后最小化应用程序)然后从最近重新打开应用程序,它会重新打开到没有片段的容器活动。在演示者中仅引发了 ActivityLifetimeListener_ActivityChanged 方法。或许可以挂钩到该方法并在此时正确呈现片段,但我还没有设法做到这一点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-19
      • 2011-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-04
      相关资源
      最近更新 更多