{"id":11573,"date":"2014-06-23T13:00:25","date_gmt":"2014-06-23T17:00:25","guid":{"rendered":"http:\/\/blog.xamarin.com\/?p=11573"},"modified":"2014-06-23T13:00:25","modified_gmt":"2014-06-23T17:00:25","slug":"using-custom-controls-in-xamarin-forms-on-android","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/xamarin\/using-custom-controls-in-xamarin-forms-on-android\/","title":{"rendered":"Using Custom Controls in Xamarin.Forms on Android"},"content":{"rendered":"<p>\t\t\t\tWith over 40 pages, layouts, and controls built into the Xamarin.Forms library, you are sure to find something to fit your needs when building out native mobile apps on iOS, Android, and Windows Phone. One of the key features that I love about Xamarin.Forms is that you are able to not only <a href=\"http:\/\/developer.xamarin.com\/guides\/cross-platform\/xamarin-forms\/custom-renderer\/\" title=\"How-to Customize Xamarin.Forms Controls\" target=\"_blank\">completely customize each built in-control<\/a>, but you can extend and mix-and-match platform specific APIs and custom controls. This means that if you have been building and using custom controls in your Xamarin apps you are still able to re-use them in your Xamarin.Forms mobile apps with the concept of a <b>custom renderer<\/b>. <a href=\"\/wp-content\/uploads\/sites\/44\/2019\/04\/HoloProgressBar1.png\"><img decoding=\"async\" class=\"alignright size-full wp-image-11580\" src=\"\/wp-content\/uploads\/sites\/44\/2019\/04\/HoloProgressBar1.png\" alt=\"HoloProgressBar\" width=\"200\" height=\"338\" \/><\/a><\/p>\n<p>Over the past 3 years I have built out a lot of custom controls and one of my favorite has to be this <a href=\"https:\/\/github.com\/jamesmontemagno\/MonoDroidToolkit\/wiki\/HoloCircularProgressBar\" title=\"Holo Circular Progress Bar\">circular progress bar<\/a>. It has the look and feel of the built in Android stop watch, but I re-wrote it in C# as part of my <a href=\"https:\/\/www.nuget.org\/packages\/MonoDroid.Toolkit\" title=\"Xamarin.Android Toolkit\" target=\"_blank\">Xamarin.Android Toolkit<\/a>. Of course I want to re-use this control and others in my Xamarin.Forms apps, so let&#8217;s take a look at how to take this pre-existing custom control and make a custom renderer for it.<\/p>\n<h2>Xamarin.Forms Control<\/h2>\n<p>There are two main parts to implementing a custom control with a renderer. <\/p>\n<ol>\n<li>Create your own custom Xamarin.Forms control with bindable properties.\n<li>Create a renderer in each platform that will be used to display the custom control and subscribe to property changed notifications.\n<\/ol>\n<p>This means that you can give your custom controls new functionality with the built-in data binding system in Xamarin.Forms. In my shared code project I am going to create a new control that will be used in my pages and layouts called <b>CircularProgress<\/b> and this will inherit from <b>Xamarin.Forms.View<b>. <\/b><\/b><\/p>\n<pre class=\"lang:csharp decode:true\">\nusing Xamarin.Forms;\nnamespace CustomProgressBar.CustomControls\n{\n  public class CircularProgress : View\n  {\n    ...\n  }\n}\n<\/pre>\n<h2>Bindable Properties<\/h2>\n<p>The real magic is to implement the two way data binding with custom properties in this class. I can create these with the <b>BindableProperty<\/b> class which describes what the property is and knows how to trigger a PropertyChanged Notification. Here I will implement just a few such as if the progress bar is indeterminate, the current progress, and what color the bar is.<\/p>\n<pre class=\"lang:csharp decode:true\">\n\/\/Bindable property for the progress color\npublic static readonly BindableProperty ProgressColorProperty =\n  BindableProperty.Create&lt;CircularProgress,Color&gt; (p =&gt; p.ProgressColor, Color.Red);\n\n\/\/Gets or sets the color of the progress bar\npublic Color ProgressColor {\n  get { return (Color)GetValue (ProgressColorProperty); }\n  set { SetValue (ProgressColorProperty, value); }\n}\n...\n<\/pre>\n<p>Notice here that I am using the <b>Color<\/b> property, which is a Xamarin.Forms specific color, that I am setting to Red as the default. I would do the same for other properties that I wan to bind to.<\/p>\n<h2>Circular Progress Renderer<\/h2>\n<p>With my new Xamarin.Forms control in place I can now implement the platform specific renderer in my Xamarin.Android project, which I will call <b>CircularProgressRenderer<\/b>. Each Xamarin.Forms control has a custom renderer that you can inherit from if you are customizing a built in control. However since this is completely custom View I am going to inherit from <b>ViewRenderer<\/b>.<\/p>\n<pre class=\"lang:csharp decode:true\">\nnamespace CustomProgressBar.Droid.Renderers\n{\n  public class CircularProgressRenderer \n    : ViewRenderer&lt;CircularProgress, HoloCircularProgressBar&gt; {\n    ...\n  }\n}\n<\/pre>\n<p>This type of renderer on Android inherits from View, which means Xamarin.Forms will handle all of the size calculations and normal properties of a standard Android View. All I have to do now is create my custom control and tell the renderer to display it. I can do this in our <b>OnElementChanged<\/b> method where I have access to two very important properties. <\/p>\n<ul>\n<li>First is the <b>Element<\/b>, which is our Xamarin.Forms <b>CircularProgress<\/b> control I created earlier with custom properties.<\/li>\n<li>Second is the <b>Control<\/b> which I am able to set to whatever I would like with the <b>SetNativeControl<\/b> method.<\/li>\n<\/ul>\n<p>Since ViewRenderer is templated, which you can see when I inherited from it my Element and Control already have the correct type of the Xamarin.Forms control and native control that I will be using. This means I will not have to do any casting, which is very nice.<\/p>\n<pre class=\"lang:csharp decode:true\">\nprotected override void OnElementChanged (ElementChangedEventArgs&lt;CircularProgress&gt; e){\n  base.OnElementChanged (e);\n\n  if (e.OldElement != null || this.Element == null)\n    return;\n\n  var progress = new HoloCircularProgressBar (Forms.Context) {\n    Max = Element.Max,\n    Progress = Element.Progress,\n    Indeterminate = Element.Indeterminate,\n    ProgressColor = Element.ProgressColor.ToAndroid(),\n    ProgressBackgroundColor = Element.ProgressBackgroundColor.ToAndroid(),\n    IndeterminateInterval = Element.IndeterminateSpeed };\n\n  SetNativeControl (progress);\n}\n<\/pre>\n<p>Here I am creating a new HoloCircularProgressBar from my own personal library of controls and when created I set all of the controls properties to the Xamarin.Forms control that I created and have access to before I call <b>SetNativeControl<\/b>. To get the control to show up in the actual view all I need to do is set a special <b>ExportRenderer<\/b> so Xamarin.Forms knows that my Android project has implemented this control.<\/p>\n<pre class=\"lang:csharp decode:true\">\n[assembly:ExportRenderer(typeof(CircularProgress), typeof(CircularProgressRenderer))]\nnamespace CustomProgressBar.Droid.Renderers\n{\n  ...\n}\n<\/pre>\n<p>With that in place if I setup my main page in my App.cs and use my new <b>CircularProgress<\/b> control it now shows up and renders my HoloCircularProgressBar!<\/p>\n<pre class=\"lang:csharp decode:true\">\nreturn new ContentPage {\n  Content = new CircularProgress {\n    Progress = 25\n  }\n};\n<\/pre>\n<p><img decoding=\"async\" src=\"\/wp-content\/uploads\/sites\/44\/2019\/04\/Xamarin.Forms-Circular-Progress1.png\" alt=\"Xamarin.Forms Circular Progress\" width=\"200\" height=\"338\" class=\"aligncenter size-full wp-image-11590\" \/><\/p>\n<h2>Handling Property Changes<\/h2>\n<p>I can also listen for property changed notifications in my custom control. This means I can react to any action users are performing when interacting with the Xamarin.Forms control. To do this all I need to do is override the <b>OnElementPropertyChanged<\/b> method, which is triggered whenever any bindable property is changed. The arguments that get passed in contain the property name that changed and I just need to compare it with the properties I set to update the custom control.<\/p>\n<pre class=\"lang:csharp decode:true\">\nprotected override void OnElementPropertyChanged (object sender, PropertyChangedEventArgs e) {\n  base.OnElementPropertyChanged (sender, e);\n  if (this.Element == null || this.Control == null)\n    return;\n\n  if (e.PropertyName == CircularProgress.IndeterminateProperty.PropertyName) {\n    Control.Indeterminate = Element.Indeterminate;\n  } else if (e.PropertyName == CircularProgress.ProgressProperty.PropertyName) {\n    Control.Progress = Element.Progress;\n  }\n  ...\n}\n<\/pre>\n<h2>Bringing it all together<\/h2>\n<p>With this code in place, I can now add a few more controls to my page that will allow me to manipulate the control directly. For instance I can add a few buttons to increase or decrease the progress, set it to indeterminate, and even bind a Slider control to change the speed.<\/p>\n<pre class=\"lang:csharp decode:true\">\nvar increase = new Button { Text = &quot;+5&quot; };\nvar decrease = new Button { Text = &quot;-5&quot; };\nvar indeterminate = new Button { Text = &quot;Indeterminate&quot; };\n\nincrease.Clicked += (sender, args) =&gt; progressBar.Progress += 5;\ndecrease.Clicked += (sender, args) =&gt; progressBar.Progress -= 5;\nindeterminate.Clicked += (sender, args) =&gt; progressBar.Indeterminate = !progressBar.Indeterminate;\n\nvar slider = new Slider (50, 150, 100);\nslider.ValueChanged += (sender, args) =&gt; progressBar.IndeterminateSpeed = (int)slider.Value;\n<\/pre>\n<p><img decoding=\"async\" class=\"alignright size-full wp-image-11577\" src=\"\/wp-content\/uploads\/sites\/44\/2019\/04\/Circular.gif\" alt=\"Circular Progress Bar Animating n Xamarin.Forms\" width=\"194\" height=\"345\" \/>That is it! A fully functional and custom data bound circular progress bar all in around 100 lines of code! Here is what it looks like in action.<\/p>\n<p>To learn more about customizing your Xamarin.Forms controls and applications be sure to read our <a href=\"http:\/\/developer.xamarin.com\/guides\/cross-platform\/xamarin-forms\/\" title=\"Xamarin.Forms Documentation\">thorough documentation<\/a> and you can download the full <a href=\"https:\/\/github.com\/jamesmontemagno\/Xamarin.Forms-Android-CustomProgressBar\" title=\"Download source code from GitHub\" target=\"_blank\">source code for this project from my GitHub<\/a> including a complete XAML example. <\/p>\n<p><a href=\"http:\/\/forums.xamarin.com\/discussion\/18516\" title=\"Discuss in Forums\" target=\"_blank\"><em>Discuss this blog post in the Xamarin Forums<\/em><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>With over 40 pages, layouts, and controls built into the Xamarin.Forms library, you are sure to find something to fit your needs when building out native mobile apps on iOS, Android, and Windows Phone. One of the key features that I love about Xamarin.Forms is that you are able to not only completely customize each [&hellip;]<\/p>\n","protected":false},"author":544,"featured_media":39167,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[4,16],"class_list":["post-11573","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-developers","tag-xamarin-platform","tag-xamarin-forms"],"acf":[],"blog_post_summary":"<p>With over 40 pages, layouts, and controls built into the Xamarin.Forms library, you are sure to find something to fit your needs when building out native mobile apps on iOS, Android, and Windows Phone. One of the key features that I love about Xamarin.Forms is that you are able to not only completely customize each [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/11573","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/users\/544"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/comments?post=11573"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/11573\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media\/39167"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media?parent=11573"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/categories?post=11573"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/tags?post=11573"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}