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 regardless of operating system, while catering for Web applications also. We have support for Native android, iOS, Flutter and
Xamarin.
Xamarin, being one of the promising cross platform development tools, has ensured it has Material UI support as part of its packages; however, there are limitations of using Material components in directly in Xamarin forms and hence custom renderers need to be created. In this tutorial we will see how to build a Material Textfield in Xamarin forms for both iOS and Android step by side.
Hands on
Step 1
Create a new Xamarin forms project and update the Xamarin forms to latest in Nuget package manager and it should look like below.
Step 2
Install the Xamarin.iOS.MaterialComponents nuget to the iOS project and make sure the nuget is from Microsoft to ensure the official support.
Step 3
Create a Class EntryView.cs in shared project as shown below and inherit from View. For demo purposes I have not created bindable properties but viewers are free to create them and expose to XAML.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
-
- using Xamarin.Forms;
-
- namespace MaterialTextField
- {
- public class EntryView : View
- {
- }
- }
Step 4
Now open the MainPage.xaml and create one control as shown below and make sure proper namespacing is given for control.
- <?xml version="1.0" encoding="utf-8" ?>
- <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
- xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
- xmlns:d="http://xamarin.com/schemas/2014/forms/design"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- mc:Ignorable="d"
- xmlns:cntrl="clr-namespace:MaterialTextField"
- x:Class="MaterialTextField.MainPage">
-
- <StackLayout VerticalOptions="Center" HorizontalOptions="Center">
- <cntrl:EntryView WidthRequest="220" VerticalOptions="Center" HorizontalOptions="Center"/>
- </StackLayout>
-
- </ContentPage>
Step 5
Create a class named EntryViewRenderer.cs in 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.
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Linq;
- using System.Text;
-
- using Android.App;
- using Android.Content;
- using Android.OS;
- using Android.Runtime;
- using Android.Support.Design.Widget;
- using Android.Support.V7.App;
- using Android.Text;
- using Android.Views;
- using Android.Views.InputMethods;
- using Android.Widget;
- using MaterialTextField;
- using MaterialTextField.Droid;
- using Xamarin.Forms;
- using Xamarin.Forms.Platform.Android;
- [assembly: ExportRenderer(typeof(EntryView), typeof(EntryViewRenderer))]
- namespace MaterialTextField.Droid
- {
- public class EntryViewRenderer : Xamarin.Forms.Platform.Android.AppCompat.ViewRenderer<EntryView, TextInputLayout>
- {
- global::Android.Views.View view;
- EntryView entryView;
- TextInputEditText editText;
- Activity activity;
-
- public EntryViewRenderer(Context ctx) : base(ctx)
- {
-
- }
- protected override void OnElementChanged(ElementChangedEventArgs<EntryView> e)
- {
- base.OnElementChanged(e);
- if (e.NewElement != null)
- {
- entryView = e.NewElement as EntryView;
- }
- if (e.OldElement != null || Element == null)
- {
- return;
- }
- try
- {
- SetupUserInterface();
-
- }
- catch (Exception ex)
- {
- System.Diagnostics.Debug.WriteLine(@"ERROR: ", ex.Message);
- }
- }
-
-
-
- void SetupUserInterface()
- {
- activity = this.Context as Activity;
- var layout = (TextInputLayout)LayoutInflater.From(Context).Inflate(Resource.Layout.MaterialEntryLayout, null);
- editText = layout.FindViewById<TextInputEditText>(Resource.Id.editText1);
- layout.CounterEnabled = true;
- layout.CounterMaxLength = 5;
- SetNativeControl(layout);
- }
- }
- }
Step 6
Open Resources folder in Android project and add a layout named MaterialEntryLayout.xml and add the below layout code. You may customize the appearance by adding custom styles.
- <?xml version="1.0" encoding="utf-8"?>
- <android.support.design.widget.TextInputLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:id="@+id/textInputLayout"
- style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
- android:hint="Enter the value here"
- app:counterEnabled="true"
- app:counterMaxLength="5">
- <android.support.design.widget.TextInputEditText
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:id="@+id/editText1"
- android:singleLine="true" />
- </android.support.design.widget.TextInputLayout>
Step 7
In the similar way add a class named MaterialEntryRenderer.cs to an iOS project and add the code below as shown in the screenshot.
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Linq;
- using System.Text;
-
- using Foundation;
- using MaterialComponents;
- using MaterialTextField;
- using MaterialTextField.iOS;
- using UIKit;
- using Xamarin.Forms;
- using Xamarin.Forms.Platform.iOS;
-
- [assembly: ExportRenderer(typeof(EntryView), typeof(MaterialEntryRenderer))]
- namespace MaterialTextField.iOS
- {
- public class MaterialEntryRenderer:ViewRenderer<EntryView,TextField>
- {
- MaterialComponents.TextField textfield;
- MaterialComponents.TextInputControllerOutlined textfieldController;
- protected override void OnElementChanged(ElementChangedEventArgs<EntryView> e)
- {
-
- if (Control == null)
- {
- textfield = new MaterialComponents.TextField();
- textfield.HorizontalAlignment = UIControlContentHorizontalAlignment.Center;
- textfield.VerticalAlignment = UIControlContentVerticalAlignment.Center;
- textfieldController = new MaterialComponents.TextInputControllerOutlined(textfield);
- textfieldController.CharacterCountMax = 5;
- textfieldController.CharacterCounter.CharacterCount(textfield);
- textfieldController.TextInput.Placeholder = "Enter the value";
- SetNativeControl(textfield);
- }
-
- }
-
- protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
- {
- base.OnElementPropertyChanged(sender, e);
- }
- private void Textfield_EditingDidBegin(object sender, EventArgs e)
- {
- var textfield = sender as TextField;
-
- }
- }
- }
Ready for ACTION
Conclusion
I have demonstrated the creation of MaterialTextField for iOS and Android, users are encouraged to create Bindable properties and try out various texfield options. In the next part I will show new material controls in Xamarin forms. Until then stay safe and happy coding.