Mobiele apps programmeren met Xamarin – Navigatie – Praktisch voorbeeld – Login-navigatie

print

Inhoud


Wat vooraf ging


Login-navigatie

Het is niet de bedoeling om een volledige login-procedure uit te werken (dit komt later). Hier gaat het gewoon om een praktisch voorbeeld (het inloggen) dat u helpt inzicht te krijgen in hiërarchische navigatie.

Ik vertrek vanuit een bestaand project dat ik gebruik als voorbeeld en hier verder verduidelijk.

Laat ons een bekijken wat we gaan maken.

Login

Dit scherm krijgt u te zien als u de applicatie opent en niet ingelogd bent.

SignUp

Een scherm dat u een account laat aanmaken (de eigenlijke account wordt niet gemaakt).

MainPage

Het scherm dat u te zien krijgt als u correct bent ingelogd.

Het project bevat de volgende pagina’s. Ik bespreek enkel de XAML-versie al is er ook een volledige C#-versie (voor de liefhebbers).

Er zijn 2 ondersteunende klassen Constants.cs dat de gebruikersnaam en het wachtwoord bevat en Users.cs dat gebruikt kan worden om nieuwe gebruikers aan te maken.

Constants.cs

De klasse Constants.cs bevat een vaste gebruikersnaam en wachtwoord.

namespace LoginNavigation
{
	public static class Constants
	{
		public static string Username = "Xamarin";
		public static string Password = "password";
	}
}

Users.cs

De klasse Users.cs bevat de structuur voor het eventueel bijhouden van gebruikers.

namespace LoginNavigation
{
	public class User
	{
		public string Username { get; set; }
		public string Password { get; set; }
		public string Email { get; set; }
	}
}

App.cs

Zoals u reeds weet wordt in App.cs bepaalt met welke pagina uw applicatie opstart.

using Xamarin.Forms;

namespace LoginNavigation
{
	public class App : Application
	{
		public static bool IsUserLoggedIn { get; set; }

		public App ()
		{
			if (!IsUserLoggedIn) {
				MainPage = new NavigationPage (new LoginPage ());
			} else {
				MainPage = new NavigationPage (new MainPage());
			}
		}

		protected override void OnStart ()
		{
			// Handle when your app starts
		}

		protected override void OnSleep ()
		{
			// Handle when your app sleeps
		}

		protected override void OnResume ()
		{
			// Handle when your app resumes
		}
	}
}

Merk op dat er een publieke property/eigenschap wordt aangemaakt die bijhoudt of de gebruiker ingelogd is public static bool IsUserLoggedIn { get; set; }.

Afhankelijk van het al dan niet aangemeld zijn van de gebruiker wordt dan gewenste pagina geopend (toegevoegd aan de “stack” en geactiveerd).

if (!IsUserLoggedIn) {
	MainPage = new NavigationPage (new LoginPage ());
} else {
	MainPage = new NavigationPage (new MainPage());
}

LoginPage.xaml

Niets speciaal te melden over deze pagina. Het is een heel eenvoudig opgemaakte XAML (althans voor wie de cursus en de lessen tot hier gevolgd heeft).

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="LoginNavigation.LoginPage" Title="Login">
	<ContentPage.ToolbarItems>
		<ToolbarItem Text="Sign Up" Clicked="OnSignUpButtonClicked" />
	</ContentPage.ToolbarItems>
	<ContentPage.Content>
		<StackLayout VerticalOptions="StartAndExpand">
			<Label Text="Username" />
			<Entry x:Name="usernameEntry" Placeholder="username" />
			<Label Text="Password" />
			<Entry x:Name="passwordEntry" IsPassword="true" />
			<Button Text="Login" Clicked="OnLoginButtonClicked" />
			<Label x:Name="messageLabel" />
		</StackLayout>
	</ContentPage.Content>
</ContentPage>

Het enige bijzondere is misschien het gebruik van een Toolbar.

<ContentPage.ToolbarItems>
	<ToolbarItem Text="Sign Up" Clicked="OnSignUpButtonClicked" />
</ContentPage.ToolbarItems>

LoginPage.xaml.cs

De Code-behind is interessanter. Laten we ze eerst eens volledig bekijken voor ik ze bespreek in detail.

using System;
using Xamarin.Forms;

namespace LoginNavigation
{
	public partial class LoginPage : ContentPage
	{
		public LoginPage ()
		{
			InitializeComponent ();
		}

		async void OnSignUpButtonClicked (object sender, EventArgs e)
		{
			await Navigation.PushAsync (new SignUpPage ());
		}

		async void OnLoginButtonClicked (object sender, EventArgs e)
		{
			var user = new User {
				Username = usernameEntry.Text,
				Password = passwordEntry.Text
			};

			var isValid = AreCredentialsCorrect (user);
			if (isValid) {
				App.IsUserLoggedIn = true;
				Navigation.InsertPageBefore (new MainPage (), this);
				await Navigation.PopAsync ();
			} else {
				messageLabel.Text = "Login failed";
				passwordEntry.Text = string.Empty;
			}
		}

		bool AreCredentialsCorrect (User user)
		{
			return user.Username == Constants.Username && user.Password == Constants.Password;
		}
	}
}

Buiten de constructor zijn er nog 3 functies (2 events en een functie).

Het klikken op de SignUp-knop, in de toolbar, zal u naar de gewenste pagina brengen.

async void OnSignUpButtonClicked (object sender, EventArgs e)
{
	await Navigation.PushAsync (new SignUpPage ());
}

Het klikken op de Login-knop zal eerst een nieuwe gebruiker aanmaken.

var user = new User {
	Username = usernameEntry.Text,
	Password = passwordEntry.Text
};

Vervolgens wordt gekeken of de gebruiker zich correct ingelogd heeft. Hiertoe wordt gebruik gemaakt van een eigen functie. U weet dat de gebruiksnaam en het wachtwoord zich in de klasse Constants.cs bevindt.

var isValid = AreCredentialsCorrect (user);
...
bool AreCredentialsCorrect (User user)
{
	return user.Username == Constants.Username && user.Password == Constants.Password;
}

Als het inloggen gevalideerd is wordt de gebruiker als ingelogd aangeduid:

App.IsUserLoggedIn = true;

Wordt de MainPage voor de huidige pagina ingevoegd:

Navigation.InsertPageBefore (new MainPage (), this);

en wordt tenslotte de huidige pagina van de “stack” verwijderd.

await Navigation.PopAsync ();

Indien het inloggen niet gelukt is verschijnen de gepaste foutmeldingen.

if (isValid) {
	App.IsUserLoggedIn = true;
	Navigation.InsertPageBefore (new MainPage (), this);
	await Navigation.PopAsync ();
} else {
	messageLabel.Text = "Login failed";
	passwordEntry.Text = string.Empty;
}

SignUpPage.xaml

Ook hier is de XAML vrij eenvoudig.

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="LoginNavigation.SignUpPage" Title="Sign Up">
	<ContentPage.Content>
		<StackLayout VerticalOptions="StartAndExpand">
			<Label Text="Username" />
			<Entry x:Name="usernameEntry" Placeholder="username" />
			<Label Text="Password" />
			<Entry x:Name="passwordEntry" IsPassword="true" />
			<Label Text="Email address" />
			<Entry x:Name="emailEntry" />
			<Button Text="Sign Up" Clicked="OnSignUpButtonClicked" />
			<Label x:Name="messageLabel" />
		</StackLayout>
	</ContentPage.Content>
</ContentPage>

SignUpPage.xaml.cs

We bekijken de code-behind eerst opnieuw in zijn geheel.

using System;
using System.Linq;
using Xamarin.Forms;

namespace LoginNavigation
{
	public partial class SignUpPage : ContentPage
	{
		public SignUpPage ()
		{
			InitializeComponent ();
		}

		async void OnSignUpButtonClicked (object sender, EventArgs e)
		{
			var user = new User () {
				Username = usernameEntry.Text,
				Password = passwordEntry.Text,
				Email = emailEntry.Text
			};

			// Sign up logic goes here

			var signUpSucceeded = AreDetailsValid (user);
			if (signUpSucceeded) {
				var rootPage = Navigation.NavigationStack.FirstOrDefault ();
				if (rootPage != null) {
					App.IsUserLoggedIn = true;
					Navigation.InsertPageBefore (new MainPage (), Navigation.NavigationStack.First ());
					await Navigation.PopToRootAsync ();
				}
			} else {
				messageLabel.Text = "Sign up failed";
			}
		}

		bool AreDetailsValid (User user)
		{
			return (!string.IsNullOrWhiteSpace (user.Username) && !string.IsNullOrWhiteSpace (user.Password) && !string.IsNullOrWhiteSpace (user.Email) && user.Email.Contains ("@"));
		}
	}
}

Bij het klikken op de SignUp-knop wordt een nieuwe gebruiker aangemaakt.

var user = new User () {
	Username = usernameEntry.Text,
	Password = passwordEntry.Text,
	Email = emailEntry.Text
};

Vervolgens wordt gekeken of het inschrijven gelukt is. Hiertoe wordt opnieuw een eigen functie gebruikt.

var signUpSucceeded = AreDetailsValid (user);
...
bool AreDetailsValid (User user)
{
	return (!string.IsNullOrWhiteSpace (user.Username) && !string.IsNullOrWhiteSpace (user.Password) && !string.IsNullOrWhiteSpace (user.Email) && user.Email.Contains ("@"));
}

Als het inschrijven gelukt is wordt gekeken of er een root-pagina bestaat var rootPage = Navigation.NavigationStack.FirstOrDefault ();.

Indien deze bestaat wordt de gebruiker als ingelogd aangeduid:

App.IsUserLoggedIn = true;

Wordt de MainPage voor de rootpagina ingevoegd:

Navigation.InsertPageBefore (new MainPage (), Navigation.NavigationStack.First ());

en wordt tenslotte de huidige pagina van de “stack” verwijderd en naar deze rootpagina gegaan.

await Navigation.PopToRootAsync ();

Indien het inloggen niet gelukt is verschijnen de gepaste foutmeldingen.

if (signUpSucceeded) {
	var rootPage = Navigation.NavigationStack.FirstOrDefault ();
	if (rootPage != null) {
		App.IsUserLoggedIn = true;
		Navigation.InsertPageBefore (new MainPage (), Navigation.NavigationStack.First ());
		await Navigation.PopToRootAsync ();
	}
} else {
	messageLabel.Text = "Sign up failed";
}

MainPage.xaml

De XAML is opnieuw vrij eenvoudig maar bevat wel een toolbar met een Logout-knop.

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="LoginNavigation.MainPage" Title="Main Page">
	<ContentPage.ToolbarItems>
		<ToolbarItem Text="Logout" Clicked="OnLogoutButtonClicked" />
	</ContentPage.ToolbarItems>
	<ContentPage.Content>
		<StackLayout>
			<Label Text="Main app content goes here" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" />
		</StackLayout>
	</ContentPage.Content>
</ContentPage>

MainPage.xaml.cs

De Code-behind bevat de code voor de Logout-knop. Deze code moet u ondertussen bekend zijn.

using System;
using Xamarin.Forms;

namespace LoginNavigation
{
	public partial class MainPage : ContentPage
	{
		public MainPage ()
		{
			InitializeComponent ();
		}

		async void OnLogoutButtonClicked (object sender, EventArgs e)
		{
			App.IsUserLoggedIn = false;
			Navigation.InsertPageBefore (new LoginPage (), this);
			await Navigation.PopAsync ();
		}
	}
}

Behandelde Basiscompetenties uit de module ICT Programmeren – Integratie externe functionaliteiten

  • IC BC017 – kan ICT veilig en duurzaam gebruiken
  • IC BC256 – kan diverse elementen tot een nieuw betekenisvol geheel samenstellen
  • IC BC288 – kan ICT-problemen oplossen

Geef een reactie

  • Abonneer je op deze website d.m.v. e-mail

    Voer je e-mailadres in om je in te schrijven op deze website en e-mailmeldingen te ontvangen van nieuwe berichten.