导航后清除整个返回堆栈
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
方法。也许可以连接到该方法并在那时正确呈现片段,但我还没有设法做到这一点。
有没有办法在导航到特定 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
方法。也许可以连接到该方法并在那时正确呈现片段,但我还没有设法做到这一点。