Introduction to Xamarin.Forms for Android Developers (Part 5)
This cross-platform tutorial for Android developers shows how to use Activity objects and navigation when developing an app with Xamarin.Forms.
Join the DZone community and get the full member experience.
Join For FreeIntroduction
In Android programming, Activity objects are used to display information to users and the Intent objects are used to navigate among the Activities. In Xamarin.Forms, we will be familiar with pages, which is similar to activities, and the NavigationPage object, which is similar to Intent object.
Pages
In the previous posts, we went over the basics of layouts and views in Xamarin.Forms, however, we worked within a single page. In the real world, mobile apps are made of multiple pages.
Xamarin.Forms provides many page objects that we can use to set up the UI of our applications and all of them derive from the abtract Page class. The following table describes available pages in Xamarin.Forms:
Page type |
Description |
ContentPage |
Display a single view object |
TabbedPage |
Facilitates navigating among child pages using tabs |
CarouselPage |
Facilitates using the swipe gesture among child pages |
MasterDetailPage |
Manages two separate panes, which includes a flyout control |
NavigationPage |
Provides the infrastructure for navigating among pages |
We can create the page objects in three ways:
- Using XAML
- Using C# code
- Using item templates are provided by Visual Studio
In order to follow the examples in this post, we also create a new Xamarin.Forms application named NavigApp.
The ContentPage
The ContentPage is the simplest page object and allows for displaying a single visual element (or control in the previous post). By default, when we create successfully the NavigApp application, the content of the MainPage.xaml file can look like this:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:NavigApp"
x:Class="NavigApp.MainPage">
<Label Text="Welcome to Xamarin.Forms!"
VerticalOptions="Center"
HorizontalOptions="Center" />
</ContentPage>
In XAML code above, the ContentPage object can be created by using the <ContentPage> element and its attributes. This ContentPage object displays a single visual element, the Label element. The code-behind file (MainPage.xaml.cs):
namespace NavigApp
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
}
}
We can also create the ContentPage by using the item templates:
- Right-click the NavigApp project in the Solution Explorer window and select Add > New Item…
- Next, select options and fill out something in the Add New Item dialog as the following screenshot:
Note that we can select the Content Page item, which is XAML template, or the Content Page (C#) item – which is C# code template. The ContentPage can be used individually or as the content of other pages (as you'll see later).
The MasterDetailPage
The MasterDetailPage allows we to split contents into two related parts: a master part that presents items and a detail part that presents details about items on the master part. The following XAML code (MainPage.xaml file) will demonstrate how to create a MasterDetailPage object and both its master and detail parts are represented by the ContentPage objects:
<?xml version="1.0" encoding="utf-8" ?>
<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:NavigApp"
x:Class="NavigApp.MainPage" >
<MasterDetailPage.Master>
<ContentPage Title="Content Page">
<Label Text="This is the Master" HorizontalOptions="Center"
VerticalOptions="Center"/>
</ContentPage>
</MasterDetailPage.Master>
<MasterDetailPage.Detail>
<ContentPage>
<Label Text="This is the Details" HorizontalOptions="Center"
VerticalOptions="Center"/>
</ContentPage>
</MasterDetailPage.Detail>
</MasterDetailPage>
Note that we must insert the Title property for the <MasterDetailPage.Master> 's the <ContentPage> element. The contents of the code-behind file (MainPage.xaml.cs), respectively, will look like this:
namespace NavigApp
{
public partial class MainPage : MasterDetailPage
{
public MainPage()
{
InitializeComponent();
}
}
}
Result:
You can swipe from the left to enable the master flyout:
And swipe back to hide it. An important note from the Microsoft docs:
"The master page of a MasterDetailPage should always be a ContentPage instance, and that the detail page should only be populated with TabbedPage, NavigationPage, and ContentPage instances. This will help to ensure a consistent user experience across all platforms."
You can also add a MasterDetailPage object by adding the item template from VisualStudio:
The TabbedPage
The TabbedPage object is used in the cases that you need to categorize multiple pages by topic or by activity type. You can group multiple ContentPage objects into tabs as the following XAML code (MainPage.xaml):
<?xml version="1.0" encoding="utf-8" ?>
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:NavigApp"
x:Class="NavigApp.MainPage" >
<TabbedPage.Children>
<ContentPage Title="First">
<Label Text="This is the first page" HorizontalOptions="Center" VerticalOptions="Center"/>
</ContentPage>
<ContentPage Title="Second">
<Label Text="This is the second page" HorizontalOptions="Center" VerticalOptions="Center"/>
</ContentPage>
<ContentPage Title="Third">
<Label Text="This is the third page" HorizontalOptions="Center" VerticalOptions="Center"/>
</ContentPage>
</TabbedPage.Children>
</TabbedPage>
And the code-behind (MainPage.xaml.cs) recpestively:
namespace NavigApp
{
public partial class MainPage : TabbedPage
{
public MainPage()
{
InitializeComponent();
}
}
}
The results look like this:
As you can see, we organized multiple ContentPage objects into TabbedPage.Children collection and we must also provide a Title, which is the title of each tab, to each ContentPage.
We can also add a TabbedPage object by adding the item template from Visual Studio:
The CarouselPage
The CarouselPage is similar to the TabbedPage, but instead of having tabs, we can use the swipe gesture to switch among child pages. The following XAML code will demonstrate a gallery of pictures using the CarouselPage:
<?xml version="1.0" encoding="utf-8" ?>
<CarouselPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:NavigApp"
x:Class="NavigApp.MainPage" >
<CarouselPage.Children>
<ContentPage Title="First">
<Image Source="cat.jpg" HorizontalOptions="Center" VerticalOptions="Center"/>
</ContentPage>
<ContentPage Title="Second">
<Image Source="dog.jpg" HorizontalOptions="Center" VerticalOptions="Center"/>
</ContentPage>
<ContentPage Title="Third">
<Image Source="mouse.jpg" HorizontalOptions="Center" VerticalOptions="Center"/>
</ContentPage>
</CarouselPage.Children>
</CarouselPage>
And the code-behind, respectively:
namespace NavigApp
{
public partial class MainPage : CarouselPage
{
public MainPage()
{
InitializeComponent();
}
}
}
The result:
Swiping to the second page:
And the third page:
Note that we must import the pictures to the Resource>drawable folder in the Android project:
Navigating Between Pages
In theory, to move from one page to another, an application will push a new page onto the navigation stack, where it will become the active page, and to return back to the previous page, the application will pop the current page from the navigation stack. We can pass data from a page to another page during navigation.
In practice, the navigation includes the following operators:
- Creating a root page, which is the first page is added to a navigation stack by using the NavigationPage object, in the App.xaml.cs file.
- Navigating to the next page by pushing this page to the navigation stack. We can use methods such as the PushAsync or the PushModalAsync on the Navigation property of the current page.
- By default, we can use the Back button on the device to naviage back to previous page but we can program by using the PopAsync or the PopModalAsync on the Navigation property to pop the active page from the navigation stack.
- Passing data when navigating through a page constructor or a BindingContext.
In our NavigApp application, suppose the NagvigApp application has the MainPage.xaml as follows:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:NavigApp"
x:Class="NavigApp.MainPage"
Title="Main Page">
<StackLayout>
<Label Text="I am Main Page" HorizontalOptions="Center"
VerticalOptions="Center"/>
<Button Text="Next Page" HorizontalOptions="Center" VerticalOptions="Center"
Clicked="nextPage"/>
</StackLayout>
</ContentPage>
And the MainPage.xaml.cs:
namespace NavigApp
{
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
private void nextPage(object sender, EventArgs e)
{
}
}
}
The nextPage method is Click event handler of the Next Page button. If you run the NavigApp, the result can look like this:
We can push the MainPage to the navigation stack or the MainPage will become the root page by modifying the constructor App of the App class in the App.xaml.cs file:
namespace NavigApp
{
public partial class App : Application
{
public App ()
{
InitializeComponent();
//MainPage = new NavigApp.MainPage();
MainPage = new NavigationPage(new MainPage());
}
...
}
If you run the app now, the result will look like this:
A navigation bar is present at the top of the MainPage page that displays a title. Next, we will add a second page named SecondPage to project:
The SecondPage.xaml:
<?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="NavigApp.SecondPage"
Title="Second Page">
<ContentPage.Content>
<StackLayout>
<Label Text="Welcome to second page!"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand" />
<Button Text="Previous Page"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand"
Clicked="prevPage"/>
</StackLayout>
</ContentPage.Content>
</ContentPage>
The SecondPage.xaml.cs:
namespace NavigApp
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class SecondPage : ContentPage
{
public SecondPage ()
{
InitializeComponent ();
}
private void prevPage(object sender, EventArgs e)
{
}
}
}
To move from the MainPage page to the SecondPage page by clicking the NextPage button, we must push the SecondPage page to the navigation stack. In the nextPage method, we write something:
async private void nextPage(object sender, EventArgs e)
{
await Navigation.PushAsync(new SecondPage());
}
Note that we must add the async keyword to declaration of the nextPage method. And now, we can run app again and click the Next Page button, app will navigate to the SecondPage page:
We can navigate back to the MainPage page by clicking the Back button, however, we can do this by making some changes in the prevPage method, which is the Click event handler of the PREVIOUS PAGE button:
async private void prevPage(object sender, EventArgs e)
{
await Navigation.PopAsync();
}
When navigating, we can pass data to the MainPage page through a page constructor parameter, which is shown the following changes:
- In the App() constructor: adding a parameter to the constructor of NavigationPage
public App ()
{
InitializeComponent();
MainPage = new NavigationPage(new MainPage("Minh"));
}
<ContentPage ...>
<StackLayout>
<Label x:Name="name" Text="I am " HorizontalOptions="Center"
VerticalOptions="Center"/>
<Button .../>
</StackLayout>
</ContentPage>
- In the MainPage.xaml.cs: adding some code to the MainPage constructor:
public MainPage(string name)
{
InitializeComponent();
var lbName = this.FindByName<Label>("name");
lbName.Text += name;
}
The result:
We can also pass data to the MainPage page through a BindingContext, which will be discovered in the next article.
Conclusion
In this article, I introduced about pages and navigating among pages in Xamarin.Forms. I also introduced how to pass data when navigating by using a page constructor parameter. You can learn more about all of them by checking out the Microsoft docs.
Opinions expressed by DZone contributors are their own.
Trending
-
Unlocking the Power of AIOps: Enhancing DevOps With Intelligent Automation for Optimized IT Operations
-
How To Use Pandas and Matplotlib To Perform EDA In Python
-
Working on an Unfamiliar Codebase
-
How To Manage Vulnerabilities in Modern Cloud-Native Applications
Comments