Xamarin 表单导航和处理登录页面

Posted

技术标签:

【中文标题】Xamarin 表单导航和处理登录页面【英文标题】:Xamarin Forms Navigation and dealing with a Login Page 【发布时间】:2014-12-17 21:56:53 【问题描述】:

我正在尝试创建一个以登录页面作为第一页的应用程序。

一旦用户登录,随后的页面将位于标准页面堆栈组织中,因此我可以轻松使用 Navigation 对象中的构建并将所有内容包装在导航页面中。

例如

Login Page -> MainAppPage  |-> Category1Page -> Cat1SubPage
                           |-> Category2Page -> Cat2SubPage

我的理解是我应该用new NavigationPage() 包裹MainAppPage,然后我就可以访问Navigation 对象,从而允许我执行以下操作:

await this.Navigation.PushAsync(new Category1Page());

而且各个平台都会给我自动返回按钮支持回到上一页。

但我不希望用户以这种方式从 LoginPage -> MainAppPage 导航,因为我不希望后退按钮将他们带回登录,而不需要他们明确点击注销按钮。

那么我应该如何处理从 LoginPage -> MainApp Page 的第一个页面转换。

有没有另一种方法来拥有 2 个Primary 页面并在它们之间交换?或者有没有办法拦截 MainAppPage 上的返回按钮请求并丢弃它们?

在文档中没有找到很多关于此的信息,但这似乎是一个相当标准的要求,因此可能是 PEBKAC

【问题讨论】:

【参考方案1】:

我刚刚在 Github 上发布了这个场景的快速示例。这个想法是您首先要导航到 NavigationPage,然后在必要时(意味着用户尚未登录)以模态方式推送 LoginPage。然后,在成功登录时,只需从堆栈中弹出 LoginPage。您可以在这里查看示例,https://github.com/jamesqquick/Xamarin-Forms-Login-Navigation/blob/master/ReadMe.MD

【讨论】:

但请确保您在登录页面上设置了NavigationPage.HasBackButton="False",因为某些平台仍会有一个后退按钮,允许用户离开登录模式。 此示例的正确链接是github.com/jamesqquick/Xamarin-Forms-Login-Navigation 您应该避免将非等待的异步代码放入 ctors(至少应该等待的代码)。相反,推送模态页面并在OnAppearing 回调中直接等待它,或者在OnAppearing 中创建一个待等待的Task Initialisation 属性并将推送分配给它(参见Stephen Cleary 回答here。另一件事是代码可能从线程池线程执行,因此,您可能希望通过将其包装在 Device.BeginInvokeOnMainThread 中来保护这些导航调用 所有链接都断开了。【参考方案2】:

我至少能想到两种解决方案。

一种方法是首先创建一个 MainAppPage,然后在该页面中将 Login Page 显示为 Modal。

其他方法是创建一个特定于平台的页面,加载登录页面,并且仅在成功登录后使用特定于平台的导航导航到 MainPage(LoginPage 应该是 NoHistory 或类似的东西以避免返回)而不是表单导航(即在 android 中页面应该是单独的活动)。这涉及到更多的工作,因为您必须处理这三个平台,但它不应该有太多的开销。

也就是说,有希望在 1.3.0 中提供更好的导航。

【讨论】:

谢谢 Miha,我会研究这两种解决方案。欣赏它。【参考方案3】:

这就是我在 Android 上的工作:

protected override void OnCreate (Bundle bundle)
    base.OnCreate (bundle);

    string start = "new";
    Bundle extras = Intent.Extras;
    if (extras != null) 
        start = extras.GetString ("start");
    

    if(start == "new")
        SetPage (App.GetLoginPage (OnLoginCompleted));
     else if (start == "login") 
        SetPage (App.GetMainPage (OnSignOutCompleted));
    


void OnLoginCompleted()
    // ...
    var refresh = new Intent (this, typeof(MainActivity));
    refresh.PutExtra ("start", "login");
    StartActivity (refresh);
    Finish ();

void OnSignOutCompleted()/* mirrors OnLoginCompleted */ 

这实际上是一个带有可配置登录页面的活动。为了改变它,我们用不同的设置重新启动。这比在我的手机上导航要慢一点,但只是很明显。

【讨论】:

【参考方案4】:

正如 Miha Markic 所说,模态窗口是一个不错的选择。您还可以考虑另一件事,特别是如果您希望登录页面与其他页面具有相同的导航栏,这与我已经在下面的问题 URL 中发布的内容相同。

基本上,您会在App 类中保留对NavigationPage 的引用(我们称之为AppNavPage),然后,在显示您的登录页面时,您将登录页面放在一个单独的NavigationPage 中并且使用新的NavigationPage 和登录页面创建PushAsync()

用户成功登录后,您只需使用以下代码将当前的MainPage 替换为旧的NavigationPageApplication.Current.MainPage = App.AppNavPage

查看下面的链接以获得更好的代码示例。

https://***.com/a/32382852/3850012

【讨论】:

【参考方案5】:

我认为最好的方法是在验证登录后从堆栈中删除 LoginPage,然后它不再可用。

async void OnLoginButtonClicked (object sender, EventArgs e)

  ...
  var isValid = AreCredentialsCorrect (user);
  if (isValid) 
    App.IsUserLoggedIn = true;
    Navigation.InsertPageBefore (new MainPage (), this);
    await Navigation.PopAsync ();
   else 
    // Login failed
  

如果用户的凭据正确,MainPage 实例被插入到当前导航栈之前 页。 PopAsync 方法然后从 导航堆栈,MainPage 实例成为活动页面。

查看完整描述here

【讨论】:

以上是关于Xamarin 表单导航和处理登录页面的主要内容,如果未能解决你的问题,请参考以下文章

在 Xamarin 表单的导航页面中添加 SearchBar

在返回导航中跳过 xamarin 表单中的页面

混合 WebView 导航和导航事件在 Xamarin 表单中没有响应

从 Webview 导航到 xamarin 表单中的应用程序页面

在Xamarin中导航时出现白屏问题形成Prism MasterDetails页面

注销或返回 Xamarin 表单时如何更新 Shell 页面的内容