Jaa


Summary of Chapter 27. Custom renderers

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.

A Xamarin.Forms element such as Button is rendered with a platform-specific button encapsulated in a class named ButtonRenderer. Here is the iOS version of ButtonRenderer, the Android version of ButtonRenderer, and the UWP version of ButtonRenderer.

This chapter discusses how you can write your own renderers to create custom views that map to platform-specific objects.

The complete class hierarchy

There are four assemblies that contain the Xamarin.Forms platform-specific code. You can view the source on GitHub using these links:

Note

The WinRT assemblies mentioned in the book are no longer part of this solution.

The PlatformClassHierarchy sample displays a class hierarchy for the assemblies that are valid for the executing platform.

You'll notice an important class named ViewRenderer. This is the class you derive from when creating a platform-specific renderer. It exists in three different versions, because it's tied to the view system of the target platform:

The iOS ViewRenderer<TView, TNativeView> has generic arguments:

The Android ViewRenderer<TView, TNativeView> has generic arguments:

The UWP ViewRenderer<TElement, TNativeElement> has differently named generic arguments:

When writing a renderer, you will be deriving a class from View, and then writing multiple ViewRenderer classes, one for each supported platform. Each platform-specific implementation will reference a native class that derives from the type you specify as the TNativeView or TNativeElement parameter.

Hello, custom renderers!

The HelloRenderers program references a custom view named HelloView in its App class.

The HelloView class is included in the HelloRenderers project and simply derives from View.

The HelloViewRenderer class in the HelloRenderers.iOS project derives from ViewRenderer<HelloView, UILabel>. In the OnElementChanged override, it creates a native iOS UILabel and calls SetNativeControl.

The HelloViewRenderer class in the HelloRenderers.Droid project derives from ViewRenderer<HelloView, TextView>. In the OnElementChanged override, it creates an Android TextView and calls SetNativeControl.

The HelloViewRenderer class in the HelloRenderers.UWP and other Windows projects derives from ViewRenderer<HelloView, TextBlock>. In the OnElementChanged override, it creates a Windows TextBlock and calls SetNativeControl.

All the ViewRenderer derivatives contain an ExportRenderer attribute on the assembly level that associates the HelloView class with the particular HelloViewRenderer class. This is how Xamarin.Forms locates renderers in the individual platform projects:

Triple screenshot of Hello View

Renderers and properties

The next set of renderers implements ellipse drawing, and is located in the various projects of the Xamarin.FormsBook.Platform solution.

The EllipseView class is in the Xamarin.FormsBook.Platform platform. The class is similar to BoxView and defines just a single property: Color of type Color.

The renderers can transfer property values set on a View to the native object by overriding the OnElementPropertyChanged method in the renderer. Within this method (and within most of the renderer), two properties are available:

  • Element, the Xamarin.Forms element
  • Control, the native view or widget or control object

The types of these properties are determined by the generic parameters to ViewRenderer. In this example, Element is of type EllipseView.

The OnElementPropertyChanged override can therefore transfer the Color value of the Element to the native Control object, probably with some kind of conversion. The three renderers are:

The EllipseDemo class displays several of these EllipseView objects:

Triple screenshot of Ellipse Demo

The BouncingBall bounces an EllipseView off the sides of the screen.

Renderers and events

It is also possible for renderers to indirectly generate events. The StepSlider class is similar to the normal Xamarin.Forms Slider but allows specifying a number of discrete steps between the Minimum and Maximum values.

The three renderers are:

The renderers detect changes to the native control, and then call SetValueFromRenderer, which references a bindable property defined in the StepSlider, a change to which causes the StepSlider to fire a ValueChanged event.

The StepSliderDemo sample demonstrates this new slider.