Telerik blogs
xamarin_tips_header

Android, iOS, UWP - let's even throw in Windows Phone 8.1. The big problem with developing applications for all of those different operating systems is that, well...they are different. Other than the obvious fact that the languages used to write the apps are different, maintaining multiple code repositories to do essentially the same thing is tedious at best, and at worst can become a nightmare.

As a .Net developer, this is where Xamarin comes in. It promises to deliver mobile apps with a shared code base - however, that shared code base is on the application logic side of things. Traditional Xamarin.iOS, Xamarin.Android, and Xamarin.UWP development still require that the user interface be written separately from each other - and that is no small task.

Xamarin.Forms offers a significant time savings in this regard. Its claim to fame is that it abstracts the user interface of each platform - the individual operating system controls and navigation metaphors - into a common layer, which can be used to build applications for iOS, Android, and UWP with a both a shared application layer and user interface layer!

However, Xamarin.Forms is much more than that. This article will provide an overview of both the cross platform user interface elements as well as some other features that make Xamarin.Forms a full-fledged framework worth considering for your next mobile app.

The Basics of Xamarin.Forms

At its simplest, Xamarin.Forms is a mobile application framework for building user interfaces. The definition from Xamarin's website is:

Xamarin.Forms is a cross-platform UI toolkit that allows developers to easily create native user interface layouts that can be shared across Android, iOS, and Windows Phone.

But don't simply focus on the term "UI" in that definition and think only on-screen controls. Instead focus on the word "toolkit" as Xamarin.Forms offers so much more in addition to user interface controls that work across platforms.

Xamarin.Forms will emit a 100% native iOS, Android or UWP app - in fact the starting point of any Xamarin.Forms app is within one of those platform projects. However, that's as far as the platform-specific code needs to go. The rest of the code can all be written in one of the layers that are shared amongst all the applications.

Xamarin Forms Is More Than Controls

Xamarin.Forms provides 20+ cross-platform user interface controls, each of these controls has an API specific to Xamarin.Forms, but is emitted as its native iOS, Android or UWP counterpart. In other words a Xamarin.Forms Label control will be emitted as an iOS UILabel.

Some of the built-in Xamarin.Forms controls, as natively rendered on iOS and Android, can be seen below.

But Xamarin.Forms is much more than that.

  • It also offers up several different page layouts - including a navigation page which controls a navigation stack of other pages. A tabbed page containing other pages accessed via tabs, and a master detail page.

  • Xamarin.Forms provides a means to layout the controls within the pages via what are called Layouts, and there are several of those including Stack, Grid, Absolute, and Relative.

  • It also provides a binding engine - so a property in a class can be "bound" to a property on a control - like the Text property on a Label. This alone greatly speeds up development time.

  • A messaging serviced called Messaging Center is included - allowing various classes and components to communicate without knowing anything about each other.

  • There are a slew of utilities provided to access the underlying platform projects, so you can bring in platform-specific functionality into the core, or shared, Xamarin.Forms project. The Dependency Service is one such utility. This allows you to create functionality in a class within the a platform project, and let Xamarin.Forms take care of finding that class for you in the shared project.

  • Effects are a means by which you can create small platform-specific user interface tweaks to controls and have them applied in the shared project.

  • Custom Renderers allow you to take full control of how a control renders itself within Xamarin.Forms - thus you are able to add whatever additional appearance or functionality that you may need.

  • And with the latest version of Xamarin.Forms, you can even directly add in controls that are only supported on one platform, such as Android floating action buttons, directly into XAML files!

Let's Create an App!

In this app, I will demonstrate several of the concepts I talked about above, namely navigation pages, a grid layout, a couple of the built-in controls, and data-binding. This app is intended to be a "Hello World" for each of those concepts in order to demonstrate that Xamarin.Forms is more than just UI controls.

I will be using XAML to create the user interface of this project.

As part of this app, I want to make sure the pages appear within a navigation hierarchy. So new pages get added to the stack, and a back button press will remove them.

Within a new project, open App.xaml.cs and set the MainPage to be equal to a NavigationPage:

MainPage = new NavigationPage(new OverviewDemoPage());

OverviewDemoPage is the name of the class that will contain the main content of our app, and by virtue of being passed into the NavigationPage's constructor, it will serve as the root of the navigation hierarchy.

The content of OverviewDemoPage.xaml looks like the following:

<?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:OverviewDemo" 
        x:Class="OverviewDemo.OverviewDemoPage"
        Title="Forms Overview">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <Label BindingContext="{x:Reference theEntry}" Text="{Binding Text}"
            VerticalOptions="Center" HorizontalOptions="Center" 
            Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" />
        <Entry x:Name="theEntry" Text="Hi" VerticalOptions="Center" HorizontalOptions="FillAndExpand"
            Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" />
        <Button Text="Button 1" Grid.Row="2" Grid.Column="0" Clicked="ButtonOne_Clicked"/>
        <Button Text="Button 2" Grid.Row="2" Grid.Column="1" Clicked="ButtonTwo_Clicked"/>

    </Grid>
</ContentPage>

There are several things going on here.

First is the Grid. It is defined as 2 columns and 3 rows. The columns are defined each to take up an equal amount of space, while the bottom row is defined to take up exactly the amount of space it needs to house its contents, then the two rows on top of it will equally split the rest.

Each of the controls that follow position themselves in the Grid using Grid.Row or Grid.Column.

The Entry and the Label will take up the first and second row of the Grid respectively, but notice that they are also defined to span both columns of the Grid so that they can center themselves on screen.

A very interesting thing is the data binding setup between the Label and the Entry control. The Label has a property called BindingContext, which is the source of any data it is bound to. In this case, it is bound to the control named theEntry. Then the Text property on the Label is using that binding to get at a property in the source (theEntry control) by the name of Text.

So Label.Text is bound to whatever appears in Entry.Text. And that's a pretty neat way to introduce automatic updating of controls without having to write a lot of event handlers (and it works with regular classes as well, not only controls).

Finally, the 2 buttons will occupy the bottom row of the grid and each have half of the screen. When clicked they will invoke their respective event handlers, defined in OverviewDemoPage.xaml.cs as:

async void ButtonOne_Clicked(object sender, EventArgs e)
{
    await Navigation.PushAsync(new ChildPage(), true);
}

async void ButtonTwo_Clicked(object sender, EventArgs e)
{
    await App.Current.MainPage.DisplayAlert("Alert", "Button Two Clicked", "OK");
}

The ButtonOne_Clicked function will push a new page onto the stack, while the ButtonTwo_Clicked function will display an alert.

Obviously, this is a very simple app, but one that I think shows off the power of Xamarin.Forms with a minimal amount of code. Within this basic app we utilize navigation hierarchy, grid layouts, and data binding.

This is the app running on Android. Notice the data bound `Label` control and how it changes immediately with the Entry control. The navigation stack and alert prompt are being demo'd by the Buttons.

When to Use Xamarin.Forms?

As its name implies, Xamarin.Forms excels when collecting data - or when pages are laid out in forms. However, it can go beyond that.

With the easy access to the platform projects via the Dependency Service, Effects, Custom Renderers, or embedding native views directly into the XAML files, it is easier than ever to build a platform-specific feature rich application from Xamarin.Forms.

The easier question to answer may not be when to use Xamarin.Forms, but when not to use it?

The general rule is - anytime you will need a highly customized app for a single platform - whether a highly customized user interface or needing functionality only provided by a specific operating system - then the traditional Xamarin route is the way to go. If the app is so targeted to one specific platform - Xamarin.Forms does not make sense.

Along with that, any apps that require complex animations or games are not the best fit either - although there are libraries built for game development such as CocosSharp and UrhoSharp that are accessible from Xamarin.Forms.

However, if most (even if not all) of your app can look and act the same on all of the platforms - Xamarin.Forms is a prime candidate.

Summary

Xamarin.Forms is a powerful framework for creating cross platform applications using .Net. Not only does it provide a means to write application logic that can be shared across platforms, but also user interfaces.

Xamarin.Forms provides many user interface controls out of the box, but it does much more than that - including pages that adhere to the native platform navigation metaphors such as tabbed, master detail, and stack navigation.

A powerful data binding system is included within Xamarin.Forms, allowing properties in a class to be bound and updated by properties on a user interface control (and vice versa).

Finally, Xamarin.Forms provides many means to access and tailor an app in a platform-specific way via the dependency service, custom renderers and effects, to name a few.

But most importantly of all, Xamarin.Forms is a fun and productive framework to work with.

Building Xamarin iOS/Android/Forms apps and crave for polished UI controls? Take a look at Telerik UI for Xamarin - well engineered performant and rich UI controls, ready for your app out of the box!


Telerik Blogging Ninja
About the Author

The Telerik Team

 

Comments

Comments are disabled in preview mode.