Practical Xamarin.Forms Introduction

The cross-platform Xamarin toolset is used by developers to share code between versions of apps written multiple platforms including Android, iOS and Windows Phone. In order to further simplify development of simple forms input -driven applications, Xamarin provides a special UI kit – Xamarin.Forms. In the past, we gave a short Xamarin.Forms overview. Today, we want to dive deeper, sharing practical Xamarin.Forms tips.

Xamarin.Forms is implemented above Xamarin.iOS, Xamarin.Android and Xamarin.WinPhone. If your app can be coded using only Xamarin.Forms UI, theoretically it should allow sharing of both application logic and presentation. The same project could be built for and used on multiple platforms, without platform specific customizations.


forms-architecture

The above image illustrates Xamarin.Forms architecture with Portable Class Libraries sitting above Xamarin.iOS, Xamarin.Android and Xamarin for Windows Phone. In a nutshell, Xamarin.Forms is a collection of editors, layout panels, navigation panels etc. In order to display controls, Xamarin utilizes a concept of a renderer. Renderer is essentially a platform-specific implementation of a cross-platform Xamarin.Forms primitive. In turn, platform-specific Xamarin controls are wrappers around native controls. For example, PCL layer’s class Button is backed by ButtonRenderer implemented in Xamarin.Android, Xamarin.iOS and Xamarin.WinPhone. A layer deeper, ButtonRenderer is rendered using a native button control – UIButton on iOS.

While learning Xamarin.Forms, we uncovered various limitations. Let’s review the issues that developers face and the strategies on mitigating some of those issues.

  • One of the first problems that we noticed while working Xamarin.Forms is the incomplete implementation of WPF templates used for defining the visual appearance of the controls.
  • Since platforms and their native controls often significantly differ, renderers have to hide some of the features in order to unify their PCL-level representation. For example, Android text field control can be styled for both single and multi -line appearance, while iOS includes two controls UITextField for single-line input and UITextView for multiline. Since one control is backed by a single renderer, Xamarin.Forms PCL text input control is always multiline.
  • Sometimes, a PCL control looks or behaves differently on each platform. For example, some Windows Phone controls, such as the Switch control have wide margins. On iOS and Android, this issue is not present. Xamarin.Forms apps using such vanilla controls will render quite differently on Android/iOS and WinPhone, which could be a problem – a view with such controls that looks perfectly fine on Android and iOS may simply not fit the screen on Windows Phone.
  • An additional abstraction layer plus aggressive re-drawing/re-rendering of the view with the contained elements makes Xamarin.Forms apps noticeably slower than their native counterparts.

While the above-mentioned problems are indeed real, Xamarin.Forms can be “tuned” to mitigate some the issues. In order to overcome limitations, we will dive into the Xamarin platform. Let us try to deal with the wide margin issue.

We make a test app displaying two switches with the look defined by the below grid.

<Grid RowSpacing=”0″>
   <Grid.RowDefinitions>
       <RowDefinition Height=”Auto” />
       <RowDefinition Height=”Auto” />
   </Grid.RowDefinitions>
   <Switch Grid.Row=”0“ />
   <Switch Grid.Row=“1“ />
</Grid>

On iPhone, our app will render as:

switch_ios

The appearance on Android will be similar, however on Windows Phone the app will look as:

switch_winphone

Windows Phone switch control has a lot wider margins. Since this issue is specific to Windows Phone, we have to solve it at the Windows Phone level. While we could create a new default Windows Phone style with narrow margins, this is not a good solution since the new style would be applied to all WinPhone controls. Instead, we will adjust appearance of the switch by creating a custom switch control renderer where we can tune the visual appearance as necessary.

Control switchControl = VisualTreeHelper.GetChild(Control, 0) as Control;
Border border = VisualTreeHelper.GetChild(switchControl, 0) as Border;
Grid grid = VisualTreeHelper.GetChild(border, 0) as Grid;
grid.Height = 40;

Now, we need to return the correct size.

public override SizeRequest GetDesiredSize(double widthConstraint, double heightConstraint) {
   SizeRequest result = base.GetDesiredSize(widthConstraint, heightConstraint);
   result.Request = new Size(result.Request.Width, 40);
   return result;
}

Now, the margin is slimmed and our app looks as below.

switch_winphone_tuned

Stay tuned for more Xamarin and Xamarin.Forms tips in upcoming posts.

Please follow and like us:

Leave a Reply