xamarinxamarin.formsmaterial-designcustom-renderer

Outlined Textbox in Xamarin.Forms


I want to implement material outlined textbox in Xamarin.Forms. I had created custom renderers but not able to apply style to it. I want text box like this image https://i.sstatic.net/7pWPr.png

By creating custom renderer and inheriting from TextInputLayout displays default material textbox. https://i.sstatic.net/Ek9Vb.jpg


Solution

  • You can use Custom Renderer to custom a View which contained a material designed Entry .

    Create a EntryView in Forms:

    public class EntryView : ContentView
    {
        public static readonly BindableProperty TextProperty =
          BindableProperty.Create("Text", typeof(string), typeof(EntryView), null);
        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }
    }
    

    Second , you need to create the EntryViewRenderer in Android :

    public class EntryViewRenderer : ViewRenderer
    {
        global::Android.Views.View view;
        global::Android.Widget.EditText editText;
        EntryView entryView;
        Activity activity;
    
        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.View> e)
        {
            base.OnElementChanged(e);
            if(e.NewElement != null)
            {
                entryView= e.NewElement as EntryView;
            }
    
            if (e.OldElement != null || Element == null)
            {
                return;
            }
    
            try
            {
                SetupUserInterface();
                SetupEventHandlers();
                AddView(view);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(@"           ERROR: ", ex.Message);
            }
        }
    
        private void SetupEventHandlers()
        {
            editText.TextChanged += EditText_TextChanged;
        }
    
        private void EditText_TextChanged(object sender, Android.Text.TextChangedEventArgs e)
        {
            entryView.Text = editText.Text; 
            Console.WriteLine("chanegd +" + entryView.Text);
        }
    
        void SetupUserInterface()
        {
            activity = this.Context as Activity;
            view = activity.LayoutInflater.Inflate(Resource.Layout.EntryLayout, this, false);
    
            editText = view.FindViewById<EditText>(Resource.Id.editText1);
        }
    
        protected override void OnLayout(bool changed, int l, int t, int r, int b)
        {
            base.OnLayout(changed, l, t, r, b);
    
            var msw = MeasureSpec.MakeMeasureSpec(r - l, MeasureSpecMode.Exactly);
            var msh = MeasureSpec.MakeMeasureSpec(b - t, MeasureSpecMode.Exactly);
    
            view.Measure(msw, msh);
            view.Layout(0, 0, r - l, b - t);
        }
    }
    

    In addition , you need to add EntryLayout for this View :

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">
            <EditText
                android:id="@+id/editText1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Label"
                android:outlineSpotShadowColor="@color/cardview_shadow_start_color"/>
        </android.support.design.widget.TextInputLayout>
    
    </LinearLayout>
    

    Now , you can use it in Xaml of Xamarin Forms :

    xmlns:app18="clr-namespace:App18"
    
    <app18:EntryView Text="abc"/>
    

    The effect :

    enter image description here

    If need to modify color of outline , just add style in Resources/values/styles.xml .

      <style name="LoginTextInputLayoutStyle" parent="Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense">
        <item name="boxStrokeColor">#570dff</item>
        <item name="boxStrokeWidth">2dp</item>
        <item name="android:textColorHint">#570dff</item>
      </style>
    

    In Resources/values/colors.xml add follow code :

    <color name="mtrl_textinput_default_box_stroke_color">#570dff</color>
    

    Finally used in EntryLayout.xml :

    <android.support.design.widget.TextInputLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        style="@style/LoginTextInputLayoutStyle">
        <EditText
            android:id="@+id/editText1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="Label"/>
    </android.support.design.widget.TextInputLayout>
    

    The efect:

    enter image description here