Xamarin Forms App.OnAppLinkRequestReceived中的棱镜导航用法



我正在构建一个利用一些应用程序链接的应用程序。在下面的示例中,我希望在用户激活电子邮件中的链接时打开ResetPasswordPage。

protected override async void OnInitialized()
{
InitializeComponent();
await NavigationService.NavigateAsync("/NavigationPage/LoginPage");
}
protected override void OnAppLinkRequestReceived(Uri uri)
{
if (uri.Host.EndsWith("site.nl", StringComparison.OrdinalIgnoreCase))
{
if (uri.AbsolutePath.StartsWith(@"/appname/resetpassword/"))
{
if (uri.Segments.Length == 4)
{
string resetCode = uri.Segments[3];
NavigationParameters param = new();
param.Add(NavConst.PasswordResetCode, resetCode);
await NavigationService.NavigateAsync("ResetPasswordPage", param);
}
}
}
}

这段代码有效,但不是我所期望的(iOS和Android(。我希望ResetPasswordPage会被添加到在OnInitialized中设置的导航堆栈中,这样它就会在导航栏中包含一个后退按钮,在这种情况下会将用户带回登录页面。

但是,看起来导航堆栈被替换了。当显示ResetPasswordPage,并且用户单击硬件后退按钮时,应用程序将关闭。然而,我希望它回到用户以前的位置。

我是不是对一些导航概念理解不好,或者这可能是一个错误?

NavigationService是Prism for Xamarin.Forms中一项相当独特的服务。它为每个页面构建了新的导航,导航堆栈取决于您的导航位置。

例如,当您从MasterDetailPage/FlyoutPage的上下文进行导航时,它会理解您并没有试图在该页面顶部推送模态,而是从Detail/Flyout的上下文开始。如果NavigationService不断更新页面上下文,那么注入到MasterDetailPage/FlyoutPage的ViewModel中的导航服务将不知道它需要该页面作为导航的上下文。

这里的问题最终是,您是从应用程序的上下文中导航的,该应用程序有一个没有页面集的NavigationService。因此,即使是相对导航也将具有绝对导航的效果,从而重置Application.MainPage,因为NavigationService对另一个页面没有上下文理解。

根据您的业务需求,您有一些不同的选择。一种是做一个绝对的导航,为您提供您正在寻找的导航堆栈。

您可以选择获取当前显示的页面并更新NavigationService以了解它。在应用程序类中,您可以添加以下内容:

protected override void OnAppLinkRequestReceived(Uri uri)
{
if (NavigationService is IPageAware pa)
{
page.Page = PageUtilities.GetCurrentPage(MainPage);
}
if (someCondition)
{
// This will now navigate from relatively from the page
// returned by GetCurrentPage.
NavigationService.NavigateAsync("SomeRelativeUrl")
.OnNavigationError(HandleNavigationError);
}
}

最新更新