แชร์ผ่าน


Summary of Chapter 2. Anatomy of an app

Note

This book was published in the spring of 2016, and has not been updated since then. There is much in the book that remains valuable, but some of the material is outdated, and some topics are no longer entirely correct or complete.

In a Xamarin.Forms application, objects that occupy space on the screen are known as visual elements, encapsulated by the VisualElement class. Visual Elements can be split into three categories corresponding to these classes:

A Page derivative occupies the entire screen, or nearly the entire screen. Often, the child of a page is a Layout derivative to organize child visual elements. The children of the Layout can be other Layout classes or View derivatives (often called elements), which are familiar objects such as text, bitmaps, sliders, buttons, list boxes, and so on.

This chapter demonstrates how to create an application by focusing on the Label, which is the View derivative that displays text.

Say hello

With the Xamarin platform installed, you can create a new Xamarin.Forms solution in Visual Studio or Visual Studio for Mac. The Hello solution uses a Portable Class Library for the common code.

Note

Portable Class Libraries have been replaced by .NET Standard libraries. All the sample code from the book has been converted to use .NET standard libraries.

This sample demonstrates a Xamarin.Forms solution created in Visual Studio with no modifications. The solution consists of four projects:

  • Hello, a Portable Class Library (PCL) shared by the other projects
  • Hello.Droid, an application project for Android
  • Hello.iOS, an application project for iOS
  • Hello.UWP, an application project for the Universal Windows Platform (Windows 10 and Windows 10 Mobile)

Note

Xamarin.Forms no longer supports Windows 8.1, Windows Phone 8.1, or Windows 10 Mobile, but Xamarin.Forms applications do run on the Windows 10 desktop.

You can make any of these application projects the startup project, and then build and run the program on a device or simulator.

In many of your Xamarin.Forms programs, you won't be modifying the application projects. These often remain tiny stubs just to start up the program. Most of your focus will be the library common to all the applications.

Inside the files

The visuals displayed by the Hello program are defined in the constructor of the App class. App derives from the Xamarin.Forms class Application.

Note

The Visual Studio solution templates for Xamarin.Forms create a page with a XAML file. XAML is not covered in this book until Chapter 7.

The References section of the Hello PCL project includes the following Xamarin.Forms assemblies:

  • Xamarin.Forms.Core
  • Xamarin.Forms.Xaml
  • Xamarin.Forms.Platform

The References sections of the five application projects include additional assemblies that apply to the individual platforms:

  • Xamarin.Forms.Platform.Android
  • Xamarin.Forms.Platform.iOS
  • Xamarin.Forms.Platform.UWP
  • Xamarin.Forms.Platform.WinRT
  • Xamarin.Forms.Platform.WinRT.Tablet
  • Xamarin.Forms.Platform.WinRT.Phone

Note

The References sections of these projects no longer list the assemblies. Instead, the project file contains a PackageReference tags referencing the Xamarin.Forms NuGet package. The References section in Visual Studio lists the Xamarin.Forms package rather than the Xamarin.Forms assemblies.

Each of the application projects contains a call to the static Forms.Init method in the Xamarin.Forms namespace. This initializes the Xamarin.Forms library. A different version of Forms.Init is defined for each platform. The calls to this method can be found in the following classes:

In addition, each platform must instantiate the App class location in the shared library. This occurs in a call to LoadApplication in the following classes:

Otherwise, these application projects are normal "do nothing" programs.

PCL or SAP?

It's possible to create a Xamarin.Forms solution with the common code in either a Portable Class Library (PCL) or a Shared Asset Project (SAP). To create an SAP solution, select the Shared option in Visual Studio. The HelloSap solution demonstrates the SAP template with no modifications.

Note

Portable Class Libraries has been replaced by .NET Standard libraries. All the sample code from the book has been converted to use .NET standard libraries. Otherwise, the PCL and .NET Standard libraries are conceptually very similar.

The library approach bundles all the common code in a library project referenced by the platform application projects. With the SAP approach, the common code effectively exists in all the platform application projects and is shared among them.

Most Xamarin.Forms developers prefer the library approach. In this book, most of the solutions use a library. Those that use SAP include an Sap suffix in the project name.

With the SAP approach the code in the shared project can execute different code for the various platforms by using C# preprocessor directives (#if, #elif, and #endif) with these predefined identifiers:

  • iOS: __IOS__
  • Android: __ANDROID__
  • UWP: WINDOWS_UWP

In a shared library, you can determine what platform you're running on at runtime, as you'll see later in this chapter.

Labels for text

The Greetings solution demonstrates how to add a new C# file to the Greetings project. This file defines a class named GreetingsPage that derives from ContentPage. In this book, most projects contain a single ContentPage derivative whose name is the name of the project with the suffix Page appended.

The GreetingsPage constructor instantiates a Label view, which is the Xamarin.Forms view that displays text. The Text property is set to the text displayed by the Label. This program sets the Label to the Content property of ContentPage. The constructor of the App class then instantiates GreetingsPage and sets it to its MainPage property.

The text is displayed in the upper-left corner of the page. On iOS, this means that it overlaps the page's status bar. There are several solutions to this problem:

Solution 1. Include padding on the page

Set a Padding property on the page. Padding is of type Thickness, a structure with four properties:

Padding defines an area inside a page where content is excluded. This allows the Label to avoid overwriting the iOS status bar.

Solution 2. Include padding just for iOS (SAP only)

Set a 'Padding' property only on iOS using an SAP with a C# preprocessor directive. This is demonstrated in the GreetingsSap solution.

Solution 3. Include padding just for iOS (PCL or SAP)

In the version of Xamarin.Forms used for the book, a Padding property specific to iOS in either a PCL or SAP can be selected using the Device.OnPlatform or Device.OnPlatform<T> static method. These methods are now deprecated

The Device.OnPlatform methods are used to run platform-specific code or to select platform-specific values. Internally, they make use of the Device.OS static read-only property, which returns a member of the TargetPlatform enumeration:

The Device.OnPlatform methods, the Device.OS property, and the TargetPlatform enumeration are all now deprecated. Instead, use the Device.RuntimePlatform property and compare the string return value with the following static fields:

  • iOS, the string "iOS"
  • Android, the string "Android"
  • UWP, the string "UWP", referring to the Universal Windows Platform

The Device.Idiom static read-only property is related. This returns a member of the TargetIdiom, which has these members:

For iOS and Android, the cutoff between Tablet and Phone is a portrait width of 600 units. For the Windows platform, Desktop indicates a UWP application running under Windows 10, and Phone indicates a UWP application running under Windows 10 application.

Solution 3a. Set margin on the Label

The Margin property was introduced too late to be included in the book, but it is also of type Thickness and you can set it on the Label to define an area outside the view that is included in the calculation of the view's layout.

The Padding property is only available on Layout and Page derivatives. The Margin property is available on all View derivatives.

Solution 4. Center the label within the page

You can center the Label within the Page (or put it in one of eight other places) by setting the HorizontalOptions and VerticalOptions properties of the Label to a value of type LayoutOptions. The LayoutOptions structure defines two properties:

  • An Alignment property of type LayoutAlignment, an enumeration with four members: Start, which means left or top depending on the orientation, Center, End, which means right or bottom depending on the orientation, and Fill.

  • An Expands property of type bool.

Generally these properties are not used directly. Instead, combinations of these two properties are provided by eight static read-only properties of type LayoutOptions:

HorizontalOptions and VerticalOptions are the most important properties in Xamarin.Forms layout, and are discussed in more detail in Chapter 4. Scrolling the Stack.

Here's the result with the HorizontalOptions and VerticalOptions properties of Label both set to LayoutOptions.Center:

Triple screenshot of greetings program

Solution 5. Center the text within the Label

You can also center the text (or place it in eight other locations on the page) by setting the HorizontalTextAlignment and VerticalTextAlignment properties of Label to a member of the TextAlignment enumeration:

  • Start, meaning left or top (depending on orientation)
  • Center
  • End, meaning right or bottom (depending on orientation)

These two properties are defined only by Label, whereas the HorizontalAlignment and VerticalAlignment properties are defined by View and inherited by all View derivatives. The visual results might seem similar, but they are very different as the next chapter demonstrates.