// Tutorial //

Android TextInputLayout Example

Published on August 3, 2022
Default avatar
By Anupam Chugh
Developer and author at DigitalOcean.
Android TextInputLayout Example

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

In this tutorial, we’ll be looking in depth at the features that Android TextInputLayout provides us. Android TextInputLayout is a design component that comes with the Material Design Support Library.

Android TextInputLayout

Android TexInputLayout extends LinearLayout. The primary use of a TextInputLayout is to act as a wrapper for EditText(or its descendant) and enable floating hint animations. Rule of Thumb : TextInputLayout should wrap TextInputEditText instead of the normal EditText. Reason? TextInputEditText is a sub-class of EditText and is designed for use as a child of TextInputLayout. Furthermore, using an EditText instead would shoot us a warning : EditText added is not a TextInputEditText. Please switch to using that class instead. TextInputLayout has much more to offer than just displaying floating hint labels.

Android TextInputLayout Features

Some of the features that we’ll be covering in this tutorial are :

  1. Enabling/Disabling floating hints
  2. Enabling/Disabling floating hint animation
  3. Displaying Error Messages
  4. Showing Character Counter
  5. Alarming the user when the Character Count Exceeds its limit
  6. Customising the Text Appearance for floating hint, error label, character counter
  7. Password Visibility Toggle

We’ll look at each of these features and implement them in an Android Studio Project.

Android TextInputLayout Example Project Structure

android textinputlayout example project structure This is a single Activity application. We’ll be doing all the stuff inside the layout, activity and styles.xml and colors.xml files. Firstly, add the dependency for the design support library inside the build.gradle file as shown below.

compile 'com.android.support:design:25.3.1'

Enabling/Disabling Floating Hints

Floating Hints are enabled by default in a TextInputLayout. To disable it we need to add the following attribute inside the tag : app:hintEnabled="false". The below xml code is from the activity_main.xml layout and has three EditText fields.

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:context="com.journaldev.featuresoftextinputlayout.MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">


        <android.support.design.widget.TextInputEditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/activity_horizontal_margin"
            android:hint="TextInputEditText" />


        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_margin="@dimen/activity_horizontal_margin">

            <android.support.design.widget.TextInputEditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Floating Hint Enabled Default" />

        </android.support.design.widget.TextInputLayout>


        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/activity_horizontal_margin"
            app:hintEnabled="false">

            <android.support.design.widget.TextInputEditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Floating Hint Disabled" />

        </android.support.design.widget.TextInputLayout>

</LinearLayout>
</ScrollView>

The third EditText field has the floating hint disabled. Let’s see the output the above code gives us : android textinputlayout hint output

Enabling/Disabling Floating Hint animation

Similar to the previous feature, floating hint animation is enabled by default. To disable it we need to add the following attribute inside TextInputLayout tag. app:hintAnimationEnabled="false" The below xml code is from the activity_main.xml layout and has EditText fields for either of the cases.

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:context="com.journaldev.featuresoftextinputlayout.MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_margin="@dimen/activity_horizontal_margin">

            <android.support.design.widget.TextInputEditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Floating Hint Enabled Default" />

        </android.support.design.widget.TextInputLayout>


        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/activity_horizontal_margin"
            app:hintAnimationEnabled="false">

            <android.support.design.widget.TextInputEditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Hint Animation Disabled" />

        </android.support.design.widget.TextInputLayout>

</LinearLayout>
</ScrollView>

The output of the above code is shown below. android textinputlayout hint animation output It’s noteworthy to mention that the second EditText field doesn’t animate the floating hint when focused.

Styling the hint TextAppearance

To use a custom textColor and textSize for the hints the following attribute is used: app:hintTextAppearance="@style/HintText" The HintText style is written inside the styles.xml as shown below

<style name="HintText" parent="TextAppearance.Design.Hint">
        <item name="android:textSize">16sp</item>
        <item name="android:textColor">@color/colorPrimary</item>
    </style>

The below xml code is from the activity_main.xml layout and has EditText fields for either of the cases(with/without hintTextAppearance).

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:context="com.journaldev.featuresoftextinputlayout.MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_margin="@dimen/activity_horizontal_margin">

            <android.support.design.widget.TextInputEditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Floating Hint Enabled" />

        </android.support.design.widget.TextInputLayout>


        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_margin="@dimen/activity_horizontal_margin"
            app:hintTextAppearance="@style/HintText">

            <android.support.design.widget.TextInputEditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Custom Hint TextAppearance" />

        </android.support.design.widget.TextInputLayout>

</LinearLayout>
</ScrollView>

The output of the above code is shown below. android textinputlayout hint text appearance output

Character Counter

Character Counter is a feature used by quite a few applications. (Remember Twitter character limit?). Set app:counterEnabled to true and app:counterMaxLength with the maximum number of characters you want in the TextInputLayout. Character Counter is by default displayed below the EditText (bottom-right) and while writing this tutorial, there’s no way to change the position, yet. Styling the counter is similar to styling the hint text. app:counterTextAppearance is the attribute used this time. We’ve added the following style inside the styles.xml file in our project.

<style name="CounterText" parent="TextAppearance.Design.Counter">
        <item name="android:textSize">16sp</item>
        <item name="android:textColor">@color/my_pink</item>
    </style>

The below xml code is from the activity_main.xml layout and has EditText fields with a default character counter and a custom one.

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:context="com.journaldev.featuresoftextinputlayout.MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/activity_horizontal_margin"
            app:counterEnabled="true"
            app:counterMaxLength="5"
            app:hintTextAppearance="@style/HintText">

            <android.support.design.widget.TextInputEditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Character Counter Limit 10" />

        </android.support.design.widget.TextInputLayout>


        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/activity_horizontal_margin"
            app:counterEnabled="true"
            app:counterMaxLength="5"
            app:counterTextAppearance="@style/CounterText"
            app:hintTextAppearance="@style/HintText">

            <android.support.design.widget.TextInputEditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Character Counter Custom TextAppearance" />

        </android.support.design.widget.TextInputLayout>

</LinearLayout>
</ScrollView>

The output of the above code is given below. android text input layout character counter Let’s observe the above output closely.

  • The first EditText field changes its counter textColor, hint textColor and the indicator color when the character count is exceeded.
  • The second EditText field does the same but also, it changes the counter custom textColor and custom textSize when the limit exceeds.

To specify the style we need when the character counter exceeds its limit, we need to use the counterFlow attribute that we’ll be seeing next.

Character Counter Overflow

As we’d seen above when the character count exceeds the limit defined, the counter text uses the attributes defined in counterFlow. If the attributes weren’t present, it’ll stick to the default ones as we saw in the above output. We need to use the following param app:counterOverflowTextAppearance The style for CounterOverflow is present inside the styles.xml :

 <style name="CounterOverFlow" parent="TextAppearance.Design.Counter.Overflow">
        <item name="android:textSize">16sp</item>
        <item name="android:textColor">@color/my_orange</item>
    </style>

Add the below the code snippet to the previous activity_main.xml layout:

<android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/activity_horizontal_margin"
            app:counterEnabled="true"
            app:counterMaxLength="5"
            app:counterOverflowTextAppearance="@style/CounterOverFlow"
            app:counterTextAppearance="@style/CounterText"
            app:hintTextAppearance="@style/HintText">

            <android.support.design.widget.TextInputEditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="CounterOverflow CustomTextAppearance" />

        </android.support.design.widget.TextInputLayout>

Let’s run the application again. android text input layout counter overflow output

Error Label

Setting app:errorEnabled to true allows us to display an error text on condition beneath our EditText field. To style the Error Text, we’d use the attribute app:errorTextAppearance and add the following code inside our styles.xml file.

<style name="ErrorText" parent="TextAppearance.Design.Error">
        <item name="android:textSize">16sp</item>
        <item name="android:textColor">@color/my_black</item>
    </style>

The below xml code is from the activity_main.xml layout and has EditText fields for a default error label and a custom one.

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:context="com.journaldev.featuresoftextinputlayout.MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <android.support.design.widget.TextInputLayout
            android:id="@+id/errorInputLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/activity_horizontal_margin"
            app:counterEnabled="true"
            app:counterMaxLength="5"
            app:counterOverflowTextAppearance="@style/CounterOverFlow"
            app:counterTextAppearance="@style/CounterText"
            app:errorEnabled="true"
            app:hintTextAppearance="@style/HintText">

            <android.support.design.widget.TextInputEditText
                android:id="@+id/errorEditText"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Default Error Label" />

        </android.support.design.widget.TextInputLayout>


        <android.support.design.widget.TextInputLayout
            android:id="@+id/customErrorInputLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/activity_horizontal_margin"
            app:counterEnabled="true"
            app:counterMaxLength="5"
            app:counterOverflowTextAppearance="@style/CounterOverFlow"
            app:counterTextAppearance="@style/CounterText"
            app:errorEnabled="true"
            app:errorTextAppearance="@style/ErrorText"
            app:hintTextAppearance="@style/HintText">

            <android.support.design.widget.TextInputEditText
                android:id="@+id/customErrorEditText"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Custom Error Label" />

        </android.support.design.widget.TextInputLayout>

</LinearLayout>
</ScrollView>

To display the error text, we’ll have to call the method setError(String) on an instance of TextInputLayout in our MainActivity.java class as shown below.

package com.journaldev.featuresoftextinputlayout;

import android.support.design.widget.TextInputEditText;
import android.support.design.widget.TextInputLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;

public class MainActivity extends AppCompatActivity {


    TextInputLayout errorInputLayout, customErrorInputLayout;
    TextInputEditText errorEditText, customErrorEditText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        errorEditText = (TextInputEditText) findViewById(R.id.errorEditText);
        errorInputLayout = (TextInputLayout) findViewById(R.id.errorInputLayout);

        customErrorEditText = (TextInputEditText) findViewById(R.id.customErrorEditText);
        customErrorInputLayout = (TextInputLayout) findViewById(R.id.customErrorInputLayout);

        errorEditText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {

                if (s.length() > errorInputLayout.getCounterMaxLength())
                    errorInputLayout.setError("Max character length is " + errorInputLayout.getCounterMaxLength());
                else
                    errorInputLayout.setError(null);

            }
        });

        customErrorEditText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {

                if (s.length() > customErrorInputLayout.getCounterMaxLength())
                    customErrorInputLayout.setError("Max character length is " + customErrorInputLayout.getCounterMaxLength());
                else
                    customErrorInputLayout.setError(null);

            }
        });


    }
}

In the above code, we add a TextChangedListener(which implements TextWatcher) on each instance of TextInputEditText. We display the error label when the current character count exceeds the counter max limit. To clear the error label we set the value inside setError() as null. The output that the above code gives us is : android textinputlayout error label Note: The indicator of the text field uses the same color as the error label. It overrides the color set by counterOverflow hence has the highest priority.

Password Visibilty Toggle

Setting app:passwordToggleEnabled to true lets you show/hide the password. To change the icon color use app:passwordToggleTint. The below xml code is from the activity_main.xml layout and has EditText fields for a password visibilty toggle (default icon and with a tint)

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:context="com.journaldev.featuresoftextinputlayout.MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/activity_horizontal_margin"
            app:counterEnabled="true"
            app:counterMaxLength="5"
            app:counterOverflowTextAppearance="@style/CounterOverFlow"
            app:counterTextAppearance="@style/CounterText"
            app:hintTextAppearance="@style/HintText"
            app:passwordToggleEnabled="true">

            <android.support.design.widget.TextInputEditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Password Visibility Toggle"
                android:inputType="textPassword" />

        </android.support.design.widget.TextInputLayout>


        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/activity_horizontal_margin"
            app:counterEnabled="true"
            app:counterMaxLength="5"
            app:counterOverflowTextAppearance="@style/CounterOverFlow"
            app:counterTextAppearance="@style/CounterText"
            app:hintTextAppearance="@style/HintText"
            app:passwordToggleEnabled="true"
            app:passwordToggleTint="@color/my_orange">

            <android.support.design.widget.TextInputEditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Password Visibility Toggle Tint"
                android:inputType="textPassword" />

        </android.support.design.widget.TextInputLayout>
</LinearLayout>
</ScrollView>

The output displayed by the above code is: android textinputlayout password toggle Note: We can use our own custom icons from password visibility toggle using app:passwordToggleDrawable. This brings an end to this tutorial. We’ve covered all the major features present in TextInputLayout. You can download the Android TextInputLayout Example Project from the link below. It includes each of the code snippets above.

Download Android TextInputLayout Project

Reference: Android Official Doc

If you’ve enjoyed this tutorial and our broader community, consider checking out our DigitalOcean products which can also help you achieve your development goals.

Learn more here


About the authors
Default avatar
Developer and author at DigitalOcean.

Still looking for an answer?

Was this helpful?

Height not increase in multiline?

- Shivaji

    how do i get type value in my java class Been trying to do this for sometime now…Do you have resources i can use

    - Brian Highforce Thomas

      Nice job

      - Isiaka

        Hi Anupam Nice article. I’m trying to run a character counter on a TextInputEditText, nested inside a TextInputLayout, which is nested inside a ConstraintLayout (instead of a LinearLayout). But it doesn’t seem to work ! Is the parent LinearLayout a requirement or just a recommendation ? I do have app.errorEnabled=“true”. I have tried LinearLayout inside ConstraintLayout but that seems to result in the TextInputEditText being hidden (somewhere) ! Also, I have the correct gradle dependencies set, and have app.counterEnabled and app.counterMaxLength set. Any thoughts would be great. Cheers.

        - Simon

          I think the dependency needs to be implementation ‘com.android.support:design:28.0.0’ now, doesn’t it?

          - Graham

            Hi, i nice guide, but i want to know one more thing, is there any way to add a custom button inside the layout like the one added to hide the password but adding my own behaviour?

            - Diego Lovera

              Hey, I have used character counter with TexinputEdittext with multiple lines but after reaching bottom constraint character counter hide behind bottom view do you have any idea why that cause…

              - Nav Singh

                hello and thanks for this toturial. I’m using the codes for textinputlayout but the activity does’nt create and app crashes. please tell me what’s the problem.

                - porya

                  I want to add to add icon as drawableLeft in textinputEditText and want it should also animate like hint. How can i do that??

                  - Raj Gar

                    Hi there, what a nice post, I am struggling with changing colour of unfocused floating hint and I can not find any solution how to change the colour in runtime. The colour that is set in xml seems to be unchangeable. Can you help me with that? Thank you. Lucia

                    - Lulu