Implementing a View - Xamarin (2023)

  • Article
  • 10 minutes to read

Download the example

Custom Xamarin.Forms UI controls should derive from the View class, which is used to place layouts and controls on the screen. This article demonstrates how to create a custom renderer for a Xamarin.Forms custom control used to display a preview video stream from the device's camera.

Each Xamarin.Forms view has a companion renderer for each platform that creates an instance of a native control. When aviewis rendered by a Xamarin.Forms application in iOS thatViewRendererClass is instantiated, which in turn instantiates a nativeUIViewControl. On the Android platform is theViewRendererClass instantiates a nativeviewControl. On the Universal Windows Platform (UWP) is theViewRendererClass instantiates a nativeFrameworkElementControl. For more information about the renderer and the native control classes that Xamarin.Forms controls map to, seeRenderer base classes and native controls.

note

Some controls on Android use fast renderers that don't consume themViewRendererClass. For more information on fast renderers, seeFast Xamarin.Forms renderers.

The following diagram illustrates the relationship between theviewand the corresponding native controls that implement it:

(Video) Develop Xamarin Apps Using the List View and Diagram Controls

Implementing a View - Xamarin (2)

The rendering process can be used to implement platform-specific customizations by creating a custom renderer for aviewon every platform. The process for this is as follows:

  1. Createa custom Xamarin.Forms control.
  2. Consumethe Xamarin.Forms custom control.
  3. Createthe custom renderer for the controls on each platform.

Each point will now be discussed in turn to: acamera previewRenderer showing a preview video stream from the device's camera. Tapping the video stream will stop and start it.

Creating the custom control

A custom control can be created by subclassingviewclass as shown in the following code example:

public class CameraPreview : View{ public static readonly BindableProperty CameraProperty = BindableProperty.Create ( propertyName: "Camera", returnType: typeof(CameraOptions), declaringType: typeof(CameraPreview), defaultValue: CameraOptions.Rear); public CameraOptions Kamera { get { return (CameraOptions)GetValue (CameraProperty); } set { SetValue (Kameraeigenschaft, Wert); } }}

Thecamera previewThe custom control is created in the .NET Standard library project and defines the API for the control. The custom control exposes aCameraproperty that controls whether the video stream from the front or rear camera should be displayed on the device. If no value is specified for theCameraproperty, when the control is created, it specifies the rear camera by default.

Consume the custom control

Thecamera previewA custom control can be referenced in XAML in the .NET Standard library project by declaring a namespace for its location and using the namespace prefix for the custom control element. The following code example shows how thecamera previewcustom control can be used from a XAML page:

<ContentPage ... xmlns:local="clr-namespace:CustomRenderer;assembly=CustomRenderer" ...> <StackLayout> <Label Text="Camera Preview:" /> <local:CameraPreview Camera="Rear" HorizontalOptions=" FillAndExpand" VerticalOptions="FillAndExpand" /> </StackLayout></ContentPage>

ThelocalNamespace prefix can be named anything. However, theclr-NamespaceAndMontageThe values ​​must match the custom control details. Once the namespace is declared, the prefix is ​​used to refer to the custom control.

The following code example shows how thecamera previewcustom control can be used from a C# page:

public class MainPageCS : ContentPage{ public MainPageCS () { ... Content = new StackLayout { Children = { new Label { Text = "Camera Preview:" }, new CameraPreview { Camera = CameraOptions.Rear, HorizontalOptions = LayoutOptions.FillAndExpand, VerticalOptions = LayoutOptions.FillAndExpand } } }; }}

An instance ofcamera previewThe custom control is used to display the preview video stream from the device's camera. Aside from optionally specifying a value for theCameraproperty, the customization of the control is done in the custom renderer.

(Video) Using View Model Approach to Bind Views Together MVVM | Xamarin Forms 2.2 App Tutorial

A custom renderer can now be added to any application project to create platform-specific camera preview controls.

Building the custom renderer on each platform

The process to create the custom renderer class on iOS and UWP is as follows:

  1. Create a subclass of theViewRenderer<T1,T2>Class that renders the custom control. The first type argument in this case should be the custom control that the renderer is intended forcamera preview. The second type argument should be the native control that implements the custom control.
  2. Overwrite theOnElementChangedmethod that renders the custom control and writes logic to customize it. This method is called when the corresponding Xamarin.Forms control is created.
  3. Add oneExportRenderer-Attribute of the custom renderer class to indicate that it is used to render the custom Xamarin.Forms control. This attribute is used to register the custom renderer with Xamarin.Forms.

The process to create the custom renderer class on Android as a fast renderer is as follows:

  1. Subclass the Android control that renders the custom control. Also indicate that the subclass implements theIVisualElementRendererAndIViewRendererinterfaces.
  2. Implement theIVisualElementRendererAndIViewRendererInterfaces in the fast renderer class.
  3. Add oneExportRenderer-Attribute of the custom renderer class to indicate that it is used to render the custom Xamarin.Forms control. This attribute is used to register the custom renderer with Xamarin.Forms.

note

It is optional for most Xamarin.Forms elements to provide a custom renderer in each platform project. If no custom renderer is registered, the default renderer for the control's base class is used. However, when rendering a, custom renderers are required in each platform projectviewElement.

The following diagram illustrates the responsibilities of each project in the sample application and the relationships between them:

Implementing a View - Xamarin (3)

Thecamera previewcustom controls are rendered by platform-specific renderer classes derived from theViewRendererClass on iOS and UWP and from theframe layoutclass on android. This results in each casecamera previewcustom control rendered with platform specific controls as shown in the screenshots below:

(Video) MVVM for Beginners: Model-View-ViewModel Architecture for Xamarin.Forms, .NET MAUI, WPF, UWP, & More

Implementing a View - Xamarin (4)

TheViewRendererclass does itOnElementChangedMethod called when the custom Xamarin.Forms control is created to render the corresponding native control. This method takes aElementChangedEventArgsParameter that containsAltesElementAndNewItemCharacteristics. These properties represent the Xamarin.Forms element that the rendererWarattached and the Xamarin.Forms element that the rendererIsattached or in the sample application is theAltesElementproperty will beNulland theNewItemproperty contains a reference to thecamera previewExample.

An overwritten version of theOnElementChangedmethod is where the instantiation and customization of the native control is done in each platform-specific renderer class. TheSetNativeControlmethod should be used to instantiate the native control, and this method also assigns the control reference to thecontrolProperty. Additionally, a reference to the rendered Xamarin.Forms control can be obtained through theElementProperty.

Possibly theOnElementChangedMethod can be called multiple times. Therefore, care must be taken when instantiating a new native control to avoid memory leaks. The approach to instantiating a new native control in a custom renderer is shown in the following code sample:

protected override void OnElementChanged (ElementChangedEventArgs<NativeListView> e){ base.OnElementChanged (e); if (e.OldElement != null) { // Unsubscribe from the event handler and clean up all resources } if (e.NewElement != null) { if (Control == null) { // Instantiate the native control and assign it to it Control property using // the SetNativeControl method } // configure the control and subscribe to the event handler }}

A new native control should only be instantiated once if thecontrolproperty isNull. Additionally, the control should only be created, configured, and subscribed to event handlers when the custom renderer is attached to a new Xamarin.Forms element. Likewise, any subscribed event handlers should only be unsubscribed when the element to which the renderer is attached changes. Adopting this approach helps create a high-performance custom renderer that doesn't suffer from memory leaks.

Important

TheSetNativeControlMethod should only be called ife.NeuesElementis notNull.

Each custom renderer class is decorated with oneExportRendererattribute that registers the renderer with Xamarin.Forms. The attribute accepts two parameters - the type name of the custom Xamarin.Forms control being rendered and the type name of the custom renderer. TheMontageAttribute prefix indicates that the attribute applies to the entire assembly.

(Video) Xamarin Android Tutorial 23 Implementing A Recycler View With Material Design

The following sections explain the implementation of each platform-specific custom renderer class.

Building the custom renderer on iOS

The following code example shows the custom renderer for the iOS platform:

[Assembly: ExportRenderer (typeof(CameraPreview), typeof(CameraPreviewRenderer))]Namespace CustomRenderer.iOS{ public class CameraPreviewRenderer : ViewRenderer<CameraPreview, UICameraPreview> { UICameraPreview uiCameraPreview; geschützte Überschreibung void OnElementChanged (ElementChangedEventArgs<CameraPreview> e) { base.OnElementChanged (e); if (e.OldElement != null) { // uiCameraPreview.Tapped kündigen -= OnCameraPreviewTapped; } if (e.NewElement != null) { if (Control == null) {uiCameraPreview = new UICameraPreview (e.NewElement.Camera); SetNativeControl (uiCameraPreview); } // uiCameraPreview.Tapped abonnieren += OnCameraPreviewTapped; } } void OnCameraPreviewTapped (Objektsender, EventArgs e) {if (uiCameraPreview.IsPreviewing) {uiCameraPreview.CaptureSession.StopRunning (); uiCameraPreview.IsPreviewing = falsch; } Else {uiCameraPreview.CaptureSession.StartRunning (); uiCameraPreview.IsPreviewing = wahr; } } ... }}

Assuming thatcontrolproperty isNull, DieSetNativeControlMethod is called to instantiate a new oneUICameraPreviewto control and give him a reference to itcontrolProperty. TheUICameraPreviewcontrol is a platform-specific custom control that uses theAVCaptureAPIs to provide the preview stream from the camera. It exposes atypedEvent handled byOnCameraPreviewGetipptMethod to stop and start video preview when tapped. Thetyped-Event subscribed to when the custom renderer is attached to a new Xamarin.Forms element and unsubscribed only when the element the renderer is attached to changes.

Building the custom renderer on Android

The following code example shows the fast renderer for the Android platform:

[assembly: ExportRenderer(typeof(CustomRenderer.CameraPreview), typeof(CameraPreviewRenderer))]Namespace CustomRenderer.Droid{ public class CameraPreviewRenderer : FrameLayout, IVisualElementRenderer, IViewRenderer { // ... CameraPreview Element; VisualElementTracker visualElementTracker; VisualElementRenderer visualElementRenderer; fragment manager fragment manager; CameraFragment cameraFragment; FragmentManager FragmentManager => fragmentManager ??= Context.GetFragmentManager(); public event EventHandler<VisualElementChangedEventArgs> ElementChanged; public event EventHandler<PropertyChangedEventArgs> ElementPropertyChanged; CameraPreview Element { get => element; set { if (element == value) { return; } var oldElement = element; element = value; OnElementChanged(new ElementChangedEventArgs<CameraPreview>(oldElement, element)); } } Public CameraPreviewRenderer(contextcontext): base(context) { VisualElementRenderer = new VisualElementRenderer(this); } void OnElementChanged (ElementChangedEventArgs<CameraPreview> e) { CameraFragment newFragment = null; if (e.OldElement != null) { e.OldElement.PropertyChanged -= OnElementPropertyChanged; cameraFragment.Dispose(); } if (e.NewElement != null) { this.EnsureId(); e.NewElement.PropertyChanged += OnElementPropertyChanged; ElevationHelper.SetElevation(this, e.NewElement); newFragment = new CameraFragment { element = element }; } FragmentManager.BeginTransaction() .Replace(Id, cameraFragment = newFragment, "camera") .Commit(); ElementChanged?.Invoke(this, new VisualElementChangedEventArgs(e.OldElement, e.NewElement)); } async void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) { ElementPropertyChanged?.Invoke(this, e); switch (e.PropertyName) { case "width": await cameraFragment.RetrieveCameraDevice(); break; } } // ... }}

In this example, theOnElementChangedmethod created aCameraFragmentobject, assuming the custom renderer is attached to a new Xamarin.Forms element. TheCameraFragmenttype is a custom class that uses theCamera2API to provide the preview stream from the camera. TheCameraFragment-Object is disposed when the Xamarin.Forms element to which the renderer is attached changes.

Building the custom renderer on UWP

The following code example shows the custom renderer for UWP:

[Assembly: ExportRenderer(typeof(CameraPreview), typeof(CameraPreviewRenderer))]Namespace CustomRenderer.UWP{ öffentliche Klasse CameraPreviewRenderer : ViewRenderer<CameraPreview, Windows.UI.Xaml.Controls.CaptureElement> { ... CaptureElement _captureElement; bool _isPreviewing; protected override void OnElementChanged(ElementChangedEventArgs<CameraPreview> e) { base.OnElementChanged(e); if (e.OldElement != null) { // Tapped kündigen -= OnCameraPreviewTapped; ... } if (e.NewElement != null) { if (Control == null) { ... _captureElement = new CaptureElement(); _captureElement.Stretch = Stretch.UniformToFill; SetupKamera(); SetNativeControl(_captureElement); } // Tapped abonnieren += OnCameraPreviewTapped; } } async void OnCameraPreviewTapped (Objektsender, TappedRoutedEventArgs e) {if (_isPreviewing) {await StopPreviewAsync(); } Else { warte auf StartPreviewAsync(); } } ... }}

Assuming thatcontrolproperty isNull, a newCaptureElementis instantiated and theSetupCameramethod called that uses theMediaCaptureAPI to provide the preview stream from the camera. TheSetNativeControlmethod is then called to assign a reference to itCaptureElementinstance tocontrolProperty. TheCaptureElementcontrol makes atypedEvent handled byOnCameraPreviewGetipptMethod to stop and start video preview when tapped. Thetyped-Event subscribed to when the custom renderer is attached to a new Xamarin.Forms element and unsubscribed only when the element the renderer is attached to changes.

note

(Video) How to Open the camera and display that image in Xamarin using Xamarin Forms

It's important to stop and discard the objects that provide access to the camera in a UWP application. Otherwise, other applications trying to access the device's camera may be disrupted. For more information, seeView the camera preview.

Summary

This article showed how to create a custom renderer for a Xamarin.Forms custom control used to display a preview video stream from the device's camera. Custom Xamarin.Forms UI controls should derive from theviewClass used to place layouts and controls on the screen.

  • CustomRendererView (Example)

Videos

1. Xamarin Android : Master Detail View
(Mahesh Kulkarni)
2. Pull-To-Refresh Everything with RefreshView in Xamarin.Forms
(Gerald Versluis)
3. Xamarin Tutorial for Beginners - Build iOS & Android Apps with C#, Visual Studio, and Xamarin.Forms
(James Montemagno)
4. Implementing NavigationService in Xamarin Forms
(Houssem Dellai)
5. Xamarin Forms Grid View [Tutorial 39]
(Xamarin Guy)
6. Implement Drag & Drop in Your Xamarin.Forms App
(Gerald Versluis)
Top Articles
Latest Posts
Article information

Author: The Hon. Margery Christiansen

Last Updated: 03/02/2023

Views: 6064

Rating: 5 / 5 (70 voted)

Reviews: 85% of readers found this page helpful

Author information

Name: The Hon. Margery Christiansen

Birthday: 2000-07-07

Address: 5050 Breitenberg Knoll, New Robert, MI 45409

Phone: +2556892639372

Job: Investor Mining Engineer

Hobby: Sketching, Cosplaying, Glassblowing, Genealogy, Crocheting, Archery, Skateboarding

Introduction: My name is The Hon. Margery Christiansen, I am a bright, adorable, precious, inexpensive, gorgeous, comfortable, happy person who loves writing and wants to share my knowledge and understanding with you.