导航到特定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
理想情况下,我想在共享代码中独立于平台执行此操作,但是如果要实现此流程,则需要自定义演示者代码,这是可以的。
答案 0 :(得分: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。覆盖OnBackPressed
中的LoginContainerActivity
,以在用户按下时最小化应用程序:
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。在MvxPresentationHint
中使用新的LogoutAsync
导航:
private async Task LogoutAsync()
=> await NavigationService.ChangePresentation(new LogoutPresentationHint());
这几乎完美。删除了整个后堆栈,并正确创建了一个新的登录ViewModels和Activity / Fragments实例。我发现的唯一警告是,如果用户回退(这会最小化该应用程序),然后从最近的状态重新打开该应用程序,则它会重新打开到没有碎片的容器活动中。演示者中仅引发ActivityLifetimeListener_ActivityChanged
方法。可能可以使用该方法并在此时正确显示片段,但我还没有设法正确解决这个问题。