Creating Material Chips In Xamarin Forms (Material Series Continued)

Introduction

 
With the ever-changing requirements and wide range of standards for mobile application development, it gets confusing for stakeholders and developers. To address the concern to some extent Google has introduced Material Design which dictates how the Mobile controls should look and behave irrespective of operating system, and catering for Web applications also. We have support for Native android, iOS, Flutter and Xamarin.
 
Xamarin, being one of the popular cross platform development tools, has ensured it has Material UI support as part of its Packages. However there are limitations of using Material components directly in Xamarin forms and hence it requires custom renderers to be created. In this tutorial we will see how to build Material Chips in Xamarin forms for Android step by step.
 
In the last blog we have seen how to create TextField; here is a  link for reference
 
We will be building the Material Chips with embedded ChipGroup as shown in the Material guide. Let’s start!!!!!!!
 

Hands on

 
Step 1
 
Create a new Xamarin forms project and update the Xamarin forms to the latest in Nuget package manager.
 
 
Step 2
 
Create a Class ChipsControl.cs in shared project as shown below and inherit from View. For the demo I have not created bindable properties, but viewers are free to create them and expose to XAML.
 
  1. public static readonly BindableProperty ChipTextProperty = BindableProperty.Create("ChipText"typeof(string), typeof(ChipsControl), default(string),defaultBindingMode:BindingMode.TwoWay,propertyChanged:ChipTextPropertyChanged);  
  2.   
  3.         private static void ChipTextPropertyChanged(BindableObject bindable, object oldValue, object newValue)  
  4.         {  
  5.             var control = (ChipsControl)bindable;  
  6.             control.ChipText = newValue.ToString();  
  7.         }  
  8.   
  9.         public string ChipText  
  10.         {  
  11.             get { return (string)GetValue(ChipTextProperty); }  
  12.             set { SetValue(ChipTextProperty, value); }  
  13.         }  
Step 3
 
Now open the MainPage.xaml and create one control as shown below and make sure proper namespacing is given for control.
 
  1. <?xml version="1.0" encoding="utf-8" ?>    
  2. <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"    
  3.              xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"    
  4.              xmlns:d="http://xamarin.com/schemas/2014/forms/design"    
  5.              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"    
  6.              mc:Ignorable="d"    
  7.              xmlns:cntrl="clr-namespace:MaterialChipsDemo"    
  8.              x:Class="MaterialChipsDemo.MainPage">    
  9.     
  10.     <StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Spacing="10">    
  11.             <cntrl:ChipsControl x:Name="chip"/>    
  12.     </StackLayout>    
  13.     
  14. </ContentPage>   
Step 4
 
Create a class named ChipsViewRenderer.cs in an Android project as shown below and add the required code from below. There will be some errors for Resources, we will be addressing this in the next step.
 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.ComponentModel;  
  4. using System.Linq;  
  5. using System.Text;  
  6.   
  7. using Android.App;  
  8. using Android.Content;  
  9. using Android.OS;  
  10. using Android.Runtime;  
  11. using Android.Support.Design.Chip;  
  12. using Android.Views;  
  13. using Android.Widget;  
  14. using Java.Lang;  
  15. using MaterialChipsDemo;  
  16. using MaterialChipsDemo.Droid;  
  17. using Xamarin.Forms;  
  18. using Xamarin.Forms.Platform.Android;  
  19. [assembly: ExportRenderer(typeof(ChipsControl), typeof(ChipsViewRenderer))]  
  20. namespace MaterialChipsDemo.Droid  
  21. {  
  22.     public class ChipsViewRenderer:Xamarin.Forms.Platform.Android.AppCompat.ViewRenderer<ChipsControl,Android.Support.Design.Chip.ChipGroup>  
  23.     {  
  24.         ChipGroup chipGroupLayout;  
  25.         ChipsControl chipsControl;  
  26.         Activity activity;  
  27.         string chipText;  
  28.         public ChipsViewRenderer(Context ctx) : base(ctx)  
  29.         {  
  30.         }  
  31.   
  32.         protected override void OnElementChanged(ElementChangedEventArgs<ChipsControl> e)  
  33.         {  
  34.             base.OnElementChanged(e);  
  35.             if (e.NewElement != null)  
  36.             {  
  37.                 chipsControl = e.NewElement as ChipsControl;  
  38.             }  
  39.             if (e.OldElement != null || Element == null)  
  40.             {  
  41.                 return;  
  42.             }  
  43.             try  
  44.             {  
  45.                // chipText = chipsControl.ChipText;  
  46.                 SetupUserInterface();  
  47.             }  
  48.             catch (System.Exception ex)  
  49.             {  
  50.                 System.Diagnostics.Debug.WriteLine(@"ERROR: ", ex.Message);  
  51.             }  
  52.         }  
  53.   
  54.         private void SetupUserInterface()  
  55.         {  
  56.             try  
  57.             {  
  58.                 activity = this.Context as Activity;  
  59.                 chipGroupLayout = (ChipGroup)LayoutInflater.From(Context).Inflate(Resource.Layout.ChipGroupXml, null);  
  60.   
  61.   
  62.   
  63.   
  64.   
  65.                 string input = "hello world xamarin Forms";  
  66.   
  67.                 var tags = input?.Split(" ");  
  68.   
  69.                 foreach (var tag in tags)  
  70.                 {  
  71.                     var chip = (Chip)LayoutInflater.From(Context).Inflate(Resource.Layout.ChipItem, null);  
  72.                     chip.Text = tag;  
  73.                     chipGroupLayout.AddView(chip);  
  74.                 }  
  75.   
  76.                 SetNativeControl(chipGroupLayout);  
  77.             }  
  78.             catch (System.Exception ex)  
  79.             {  
  80.   
  81.                 System.Diagnostics.Debug.WriteLine(@"ERROR: ", ex.Message);  
  82.             }  
  83.              
  84.         }  
  85.   
  86.         //protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)  
  87.         //{  
  88.         //    base.OnElementPropertyChanged(sender, e);  
  89.         //    var control = sender as ChipsControl;  
  90.         //    chipText = control.ChipText;  
  91.         //    SetupUserInterface();  
  92.         //}  
  93.     }  
  94. }  
Step 5
 
Open Resources folder in the Android project and add a layout named ChipGroupXml.xml and add the below layout code. You may customize the appearance by adding custom styles. 
 
  1. <?xml version="1.0" encoding="utf-8" ?>     
  2. <android.support.design.chip.ChipGroup    
  3.      xmlns:android="http://schemas.android.com/apk/res/android"    
  4.     xmlns:app="http://schemas.android.com/apk/res-auto"    
  5.     android:layout_width="wrap_content"    
  6.     android:layout_marginTop="16dp"    
  7.     android:id="@+id/chipGroup"    
  8.     android:theme="@style/Base.Theme.MaterialComponents.Light"    
  9.     android:layout_height="wrap_content">    
  10.     </android.support.design.chip.ChipGroup>  
Step 6
 
Open Resources folder in the Android project and add a layout named ChipItem.xml and add the below layout code for designing individual chips.
 
  1. <?xml version="1.0" encoding="utf-8" ?>     
  2. <android.support.design.chip.Chip    
  3.    xmlns:android="http://schemas.android.com/apk/res/android"    
  4.     xmlns:app="http://schemas.android.com/apk/res-auto"    
  5.     android:id="@+id/chipItem"    
  6.     android:layout_height="wrap_content"    
  7.     android:layout_width="wrap_content"    
  8.     android:gravity="center_horizontal"    
  9.     app:closeIcon="@drawable/ic_mtrl_chip_close_circle"    
  10.     app:chipBackgroundColor="@android:color/holo_blue_light"    
  11.     app:closeIconVisible="true"    
  12.     android:theme="@style/Base.Theme.MaterialComponents.Light"    
  13.     android:text="Cart">    
  14. </android.support.design.chip.Chip>   
Step 7
 
We are now ready to Run the app on both devices. Make sure you have added Export attributes for renderers.
 
Ready for ACTION
Android Demo
https://gifyu.com/image/Q6pr
 

Conclusion

 
I have demonstrated the Creation of MaterialChips for Android, users are encouraged to create Bindable properties and try out various texfield options. In the next part I will show how to create in iOS for Xamarin forms. Until then stay safe and happy coding.