Xamarin.Forms 101: Pages and Layouts and Views (Oh My)

Pages, layouts, and views make up the core of the Xamarin.Forms UI. Pages are the primary container, and each screen is populated by a single Page class. A page may contain variations of the Layout class, which may then hold other layouts, used for placing and sizing their contents. The purpose of pages and layouts is to contain and present views, which are controls inherited from class View.

0xam5

Page

The Page class is the primary container of each main screen in the app. Derived from Xamarin.Forms.VisualElement, Page is a base class for the creation of other top-level UI classes. Here are the primary pages: ContentPage, MasterDetailPage , NavigationPage, TabbedPage, CarouselPage. In addition to serving as containers for layouts and views, pages provide a rich menu of prefabricated screens with useful functionality that includes navigation and gesture responsiveness.

Layout

Views are placed and sized by their container class, Layout. Layouts come in a variety of flavors with different features for formatting their views. These containers allow views to be formatted precisely, loosely, absolute to the coordinate system, or relative to one another. Layouts are the soft tissue of the page, the cartilage that holds together the solid, visible aspects of the page(views). Here are the main layouts: StackLayout, AbsoluteLayout, RelativeLayout, Grid, ScrollView, Frame, ContentView.

The layout’s Content and/or Children properties contain other layouts and views. Horizontal and vertical alignment is set by the properties HorizontalOptions and VerticalOptions. Rows, columns, and cells within a layout can be padded with space, sized to expand to fill available space, or shrunk to fit their content. More on layouts in the next chapter. Xamarin.Forms layouts are derived from the View class, so everything contained by a page is actually some form of a view.

View

Views are controls, the visible and interactive elements on a page. These range from the basic views like buttons, labels, and text boxes to the more advanced views like lists and navigation. Views contain properties that determine their content, font, color, and alignment. Horizontal and vertical alignment is set by properties HorizontalOptions and VerticalOptions. Like layouts, views can be padded with space, sized to expand to fill available space, or shrunk to fit their content. Later in this chapter, we’ll code some views, then visit them again in Chapter 4 and throughout the book. These are the primary views grouped by function:

  • Basic – fundamental views: Label, Image, Button, BoxView
  • List – make a scrollable, selectable list: ListView
  • Text Entry – user entry of text strings using a keyboard: Entry, Editor
  • Selection – user choice of a wide range of fields: Picker, DatePicker, TimePicker, Stepper, Slider, Switch
  • User Feedback – notify the user of app processing status: ActivityIndicator, ProgressBar

Be careful not to confuse the Xamarin.Forms View class with a view meaning screen or presentation layer. Also, iOS refers to screens as views.

I devote an entire chapter dedicated to Pages, another to Layouts, and another to Views in my book, Xamarin Mobile Application Development. Whether you read my book or check out the Xamarin online docs and Xamarin MVP blogs, educating yourself is how to make Pages and Layouts and Views less scary and working hard for you in your own apps.

Get started with the free C# and XAML book examples on GitHub.

Dig into the Xamarin.Forms toolkit and own it.

Xamarin Navigation Design Patterns

Navigation gives a user what they need to get around an app quickly, moving from screen-to-screen with confidence and ease. This may include menus, tappable icons, buttons, tabs, and list items, as well as many types of gesture-sensitive screens to display data, information, and options to the user.

Navigation patterns are industry-standard templates for tying an app’s screens together in an elegant and usable way. The two most common visual design patterns in mobile navigation are hierarchical and modal. Out of these base navigation patterns come an entire family of derivative patterns which combine, enhance, and decorate these patterns to create the full range of mobile UI patterns available. Here is an exhaustive list of the most common mobile UI navigation patterns used in Xamarin development:

  • Hierarchical – a stack-based navigation pattern where users can move deeper into a screen hierarchy, then back out again one screen at a time using the up or back buttons
  • Modal – a screen which interrupts hierarchical navigation, often a pop-up screen with an alert or menu which the user can complete or cancel
  • Drilldown List – a list of tappable items selected to display item detail
  • Navigation Drawer – a navigation menu which slides over from the left side at the tap of an icon, typically three horizontal lines in the upper-left part of the screen known as the “hamburger”
  • Tabs – a bar containing several folder-like tabs at the top or bottom of the screen each with tappable icons or text invoking new pages
  • Springboard – also referred to as a dashboard, this is a grid of tappable icons invoking new pages
  • Carousel – horizontally-slidable screen-sized panels, sometimes containing large images

Let’s explore two of the most common navigation patterns, hierarchical and modal.

Hierarchical

Hierarchical is a stack-based pattern where users can move deeper into a screen hierarchy, then back out again one screen at-a-time using the Back or Up button. This typically involves a toolbar at the top of the screen which displays an up button in the upper-left corner of the screen when a page is selected or “drilled down into” by any means. As the user drills deeper into the menu structure, a stack is maintained with each page pushed onto it. Two buttons are used in tandem to navigate backwards, popping pages off of the stack: the up and the back button.  The back button is the curved arrow icon on the bottom of the screen, although iOS doesn’t have one. The up button is the “less than” icon in the upper-left corner. Deep navigational stacks can be traversed in this manner with page selection requiring the use of additional UI navigation patterns such as the navigation drawer, drilldown list, or popup menu.

Modal

A Modal is a single, interruptive popup or screen which comes in two flavors. The most common type floats overtop the main page and is usually an alert, dialog, or menu which the user can respond to or cancel.  Navigation reverts back to the originating page when the modal is dismissed. A modal informs the user of some important event, such as a saved record, or gives them the opportunity to provide input or direction, such as a menu or whether to commit or cancel a transaction. The second, less common, type of modal replaces the main page entirely, interrupting the hierarchical navigation stack.

The two most common modal menus in the mobile UI are the Navigation Drawer and the Action Menu. The Navigation Drawer typically slides in from the left and is triggered by the tapping of an icon in the upper-left corner of the screen (usually “the hamburger”) and displays a list of pages to navigate to.  The Action Menu typically slides in or pops up on the right side of the screen, and is invoked by tapping an icon in the upper-right corner of the screen (usually three vertical dots) and contains mostly operations (ex. Favorite This), though less frequently some navigation pages as well.  To follow this established UI pattern, remember the rule: Nav on the left, action on the right.

Hierarchical and modal UI navigation patterns are typically used as complementary techniques with hierarchical providing the skeleton of the navigational structure and modals giving the user choices for what they want to do and where they wish to go within the app as well as informational updates along the way.

Xamarin.Forms provides most of the primary navigation patterns out of the box:

  • Hierarchical navigation using NavigationPage
  • Modal using NavigationPage, alerts, and ActionSheets
  • Drill-down lists using NavigationPage, ListView, and TableView
  • Navigation drawer using MasterDetailPage
  • Tabs using TabbedPage
  • Springboard using images with gesture recognizers
  • Carousel using CarouselPage

I hope that’s enough to get you thinking about navigation in your own apps. In my book, I explore hierarchical, modal, and the rest of the navigation patterns on each platform. The navigation chapter in the book is really one its crown jewels, providing you with patterns to build just about any app you can imagine! If you want to check out the navigation patterns in code, head over to GitHub and look at chapter 6. You can use that code to lay the groundwork for just about any business app!

In last week’s post I covered the Drilldown List pattern. In upcoming posts, I’ll talk about more of the the key navigation patterns in detail.

 

Navigation Patterns: Drill-down Lists

A drill-down list is a list of tappable items selected to navigate to a new page.

978-1-4842-0215-9_Fig06-11sm

There are many ways to build them using Xamarin.Forms, and the following recipe covers the most common type: by item. Other common types include lists by page and grouped lists.

A drill-down list by item has rows that can be selected to display more information about each item: the traditional master-detail pattern. This recipe uses a ListView to bind to a data model to provide a dynamic list of tappable items. A grouped drill-down list built using TableView is useful for creating categorized static menu items but ListView is one of the most versatile tools for creating drill-down lists. Short lists can, of course, be constructed by hand by using any of the layouts filled with buttons or labels paired with gesture recognizers to handle taps. Longer lists lend themselves to data binding using ListView.

Many lists contain a bunch of items that a user wants to drill down into to reach details about each item. Use ListView to display a list of items data-bound to a data model, and then show a detail page by using
PushAsync , all wrapped in NavigationPage so the user can get back to the list. You can create your ListView using the standard Xamarin.Forms approaches, such as in my post Making a Scrollable List Using ListView. This implementation uses a list item class called DrilldownListViewByItem.

Instantiate the DrilldownListViewByItem page in the Application class’s constructor wrapped in NavigationPage.

public class App : Application
{
    public App()
    {
        MainPage = new NavigationPage(new DrilldownListViewByItem ());
    }
}

This creates the a list with a navigation bar on iOS and Android. Windows Phone doesn’t display the navigation bar.

Create a detail page called detailPage whose constructor takes ListItem as a parameter. ListItem must contain either a list item ID for a detailed lookup query or all the fields needed to display on the detail page. This detail page displays a title and description.

class DetailPage: ContentPage
{
    public detailPage(ListItem listID) { // display detail }
}

Back on the list page (DrilldownListViewByItem) when an item row is tapped, pass ListItem into the detail page, which displays the detail of that particular item.

listView.ItemTapped += (sender, args) => {
    var item = args.Item as ListItem;
    if (item == null) return;
    Navigation.PushAsync (new detailPage(item) );
    listView.SelectedItem = null;
};

Tapping a list item row triggers the ItemTapped event, and the PushAsync call instantiates a detailPage and passes in ListItem to display.

978-1-4842-0215-9_Fig06-10sm

You can see the complete book example on GitHub here.

The Drill-down List by Page pattern lets you select a ContentPage then instantiate it when it is tapped. Add a page type property to the list model and navigate to the page using the Activator.CreateInstance method.

Page page = (Page)Activator.CreateInstance(item.PageType);

Check out the book code here for the Drill-down List by Page recipe.

Making a Scrollable List Using ListView

Choosing quickly from a long list of items is one of the key offerings of the mobile UI. The limited real estate on mobile phone screens makes data grids a challenge and leads to extensive and creative use of lists. Grouping of items, scrolling, gesture-sensitivity, and images make lists one of the most versatile and reuseable data-bound tools available. Lists are to mobile development what the data grid is to web development.

Binding ListView to a data model is made easy in Xamarin.Forms through the use of ListView’s built-in adapter called ItemTemplate. Prepare your data model class and assign it to the ListView.ItemsSource property. Then bind each property of your model to the list using the ItemTemplate.SetBinding method.

Create a data model, or custom class, containing the list items. Call it ListItem.

    public class ListItem {
        public string Title { get; set; }
        public string Description { get; set; }
    }

Populate it and point the ListView’s ItemsSource property to it.

    listView.ItemsSource = new ListItem [] {
        new ListItem {Title = "First", Description="1st item"},
        new ListItem {Title = "Second", Description="2nd item"},
        new ListItem {Title = "Third", Description="3rd item"}
    };

Format list rows using ItemTemplate. Create a DataTemplate class and pass in the cell type to display. The standard cell type is TextCell, which will display a title for each row plus some detail text which you’ll add in a minute. Specify the property to display as the main row text by assigning it to the TextProperty of the list, in this case Title.

    listView.ItemTemplate = new DataTemplate (typeof(TextCell));
    listView.ItemTemplate.SetBinding(TextCell.TextProperty, "Title");

This will display the same list but from custom class ListItem instead of a List of Strings. No additional adapter needed!

978-1-4842-0215-9_Fig05-03

Add a descriptive line of text to each row by binding the DetailProperty of the TextCell.

    listView.ItemTemplate.SetBinding(TextCell.DetailProperty, "Description");

This binds the Description property of the ListItem class to the DetailProperty of the TextCell.

978-1-4842-0215-9_Fig05-04

TextCell’s font color can be set using its TextColor property and the detail font color can be set using the DetailColor property.

    var template = new DataTemplate (typeof(TextCell));
    template.SetValue(TextCell.TextColorProperty, Color.Red);
    template.SetValue (TextCell.DetailColorProperty, Color.Blue);
    listView.ItemTemplate = template;

When handling the item selection, remember to use the data model.

    listView.ItemTapped += async (sender, e)
    {
        ListItem item = (ListItem)e.Item;
        await DisplayAlert("Tapped", item.Title.ToString() + " was selected.", "OK");
        ((ListView)sender).SelectedItem = null;
    };

That’s how to build a basic ListView bound to your data model!

See the complete example on GitHub here.

Tap Into Clickable Images with GestureRecognizer

Tappable images and icons are common in mobile applications for actions and navigation. Like many Xamarin.Forms views, the Image doesn’t have a click or tap event and must be wired up using the GestureRecognizer class. A gesture recognizer is a class that can be added to many views to respond to user interaction. It currently supports just the tap gesture. The terms click and tap are used interchangeably in mobile UI development.

First we need to start with an image on our ContentPage. The Image view holds an image for display on your page from a local or online file:

    Image image = new Image
    {
        Source = “monkey.png”,
        Aspect = Aspect.AspectFit,
        HorizontalOptions = LayoutOptions.End,
        VerticalOptions = LayoutOptions.Fill
    };

This is part of a larger example which shows the monkey image at the bottom right.

Android_Code_Completeblog

Now for the gesture recognizer.

Declare the gesture recognizer and a handler to create and manage the Tapped event, then the gesture recognizer is added to the target view, an image in this case. Change the image’s Opacity to .5 in the handler, which will fade the image slightly when tapped.

    var tapGestureRecognizer = new TapGestureRecognizer();
    tapGestureRecognizer.Tapped += (s, e) => {
        image.Opacity = .5;
    };
    image.GestureRecognizers.Add(tapGestureRecognizer);

Give that a try  so you can see that the gesture recognizer works.

An alternative implementation of GestureRecognizer uses the Command property.

    image.GestureRecognizers.Add (new TapGestureRecognizer {
       Command = new Command (()=> { /*handle tap*/ }),
    });

User feedback is a crucial concept in mobile UI development. Any time a user does something in the UI there should be some subtle acknowledgment by the app. A tap, for instance, should respond to the user with visible feedback. Usually an image will gray out or have a white background for a sec when touched. Let’s do that professionally using the image’s Opacity property but adding async/await to create a slight delay in our fade without affecting the app’s performance.

Replace the Tapped handler with this one that will cause the image to fade slightly for a fraction of a second. Remember to add using System.Threading.Tasks; to the top of your file for async/await.

  tapGestureRecognizer.Tapped +=  async (sender, e) =>
        {
            image.Opacity = .5;
            await Task.Delay(200);
            image.Opacity = 1;
        };

Tapping on the image will now fade the image slightly, then back to normal, providing a responsive user experience.

In your own projects you’ll use gesture recognizers (and async/await) to actually do something when an image is tapped. If you want to see async/await in action in this example, bump up the Delay to 2000, then try and do something else in your app (like tap another button, for example) and and you’ll see that the app is still responsive. You could do many things in this Tapped handler without interrupting the flow of the app. Often when a button or image is pressed, the result should be backgrounded using async/await for an optimal user experience.

Check out this free GitHub example here. Check out my book that all this is based on here.