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
替换为旧的NavigationPage
:
Application.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
混合 WebView 导航和导航事件在 Xamarin 表单中没有响应
从 Webview 导航到 xamarin 表单中的应用程序页面