简体   繁体   中英

Xamarin Forms Navigation and dealing with a Login Page

I'm trying to create an App with a Login Page as the first page.

Once the user logs in, the pages that come after will be in a standard page stack organisation so I can easily use the build in Navigation object and wrap everything in Navigation pages.

eg

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

My understanding is that I should wrap MainAppPage with new NavigationPage() , and then I'll have access to the Navigation object allowing me to do things like this:

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

And the various platforms will give me automatic back button support to go back to the previous page.

But I don't want a user to navigate from LoginPage -> MainAppPage in this manner, because I don't want the backbutton to take them back to Login, without them explicitly hitting the logout button.

So how should I handle that first Page Transition from LoginPage -> MainApp Page.

Is there an alternative way to have 2 Primary pages and swap between them? Or is there a way to intercept the back button requests on MainAppPage and discard them?

Not finding an awful lot of info in the documentation regarding this, but it seems like a fairly standard requirement so possibly PEBKAC

I just posted a quick sample on Github for this scenario. The idea is that you want to initially navigate to your NavigationPage, then if necessary (meaning the user isn't already logged in), push the LoginPage modally. Then, on successful Login, simply pop the LoginPage from the stack. You can check out the sample here, https://github.com/jamesqquick/Xamarin-Forms-Login-Navigation/blob/master/ReadMe.MD

主页截图

I can think of at least two solutions.

One way is to create a MainAppPage first and within that page show Login Page as Modal.

Other would be to create a platform specific page, load Login Page and only upon successful login navigate to MainPage using platform specific navigation (LoginPage should be NoHistory or something like that to avoid going back) not Forms navigation (ie in Android both pages should be separate activities). This involves a bit more work since you have to deal with the three platforms but it shouldn't be much overhead.

That said there is a better navigation supposedly coming with, hopefully, 1.3.0.

This is what I have working on 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 */ }

This is effectively an activity with a configurable landing page. In order to change to it we restart with a different setting. It's a tiny bit slower than navigating on my phone but only just noticeable.

As Miha Markic said, a Modal window is a good option. One other thing you can also consider, especially if you want the login page to have the same Navigation Bar as your other pages, would be the same thing that I already posted about in the question URL below.

Basically, you would keep a reference to your NavigationPage in the App class (lets call it AppNavPage ), then, when showing your login page, you put your login page within a separate NavigationPage and do a PushAsync() with your new NavigationPage and login page.

Once the user logs in successfully, you just replace the current MainPage with your old NavigationPage using this code: Application.Current.MainPage = App.AppNavPage

Check out the link below for better code examples.

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

I think the best way would be to Remove the LoginPage from the stack once you verify login, then it's not available any longer.

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
  }
}

Provided that the user's credentials are correct, the MainPage instance is inserted into the navigation stack before the current page. The PopAsync method then removes the current page from the navigation stack, with the MainPage instance becoming the active page.

See full description here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM