Do not change TextInputLayout background on error

I manage to resolve this myself by overriding TextInputLayout like this :

public class NoChangingBackgroundTextInputLayout extends TextInputLayout {
    public NoChangingBackgroundTextInputLayout(Context context) {
        super(context);
    }

    public NoChangingBackgroundTextInputLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public NoChangingBackgroundTextInputLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public void setError(@Nullable CharSequence error) {
        ColorFilter defaultColorFilter = getBackgroundDefaultColorFilter();
        super.setError(error);
        //Reset EditText's background color to default.
        updateBackgroundColorFilter(defaultColorFilter);
    }

    @Override
    protected void drawableStateChanged() {
        ColorFilter defaultColorFilter = getBackgroundDefaultColorFilter();
        super.drawableStateChanged();
        //Reset EditText's background color to default.
        updateBackgroundColorFilter(defaultColorFilter);
    }

    private void updateBackgroundColorFilter(ColorFilter colorFilter) {
        if(getEditText() != null && getEditText().getBackground() != null)
            getEditText().getBackground().setColorFilter(colorFilter);
    }

    @Nullable
    private ColorFilter getBackgroundDefaultColorFilter() {
        ColorFilter defaultColorFilter = null;
        if(getEditText() != null && getEditText().getBackground() != null)
            defaultColorFilter = DrawableCompat.getColorFilter(getEditText().getBackground());
        return defaultColorFilter;
    }
}

So as we can see it, it reset the EditText's background to its default color after setError has been called but also in the method drawableStateChanged() because the red color filter is set when losing/getting the focus on an EditText with error too.

I'm not convinced that this is the best solution but if I don't get any better solutions, I'll mark it as resolved in meantime.


If you have custom background for your edittext view, then create a <shape.../> in your drawable folder & set it's <solid../> attribute color to transparent. For reference, here is the shape with name : shape_input_layout_edittext.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:innerRadius="200dp"
    android:shape="rectangle">
    <stroke
        android:width="1dp"
        android:color="#e2e2e2"></stroke>
    <solid android:color="#00000000"></solid>
    <corners android:radius="2dp"></corners>


</shape>

Now, inside your layout xml file, use it like :

<com.google.android.material.textfield.TextInputLayout
                android:id="@+id/inputLayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:hintEnabled="false">

                <com.google.android.material.textfield.TextInputEditText
                    android:id="@+id/edtText"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"                    
  android:background="@drawable/shape_input_layout_edittext" ..../>
</com.google.android.material.textfield.TextInputLayout>

That's it, now whenever error will populate, edittext's background will have no colour. Happy Coding!


I had same problem; after searching and hit & run I found so simple way to solve this problem-

Try this easiest way -

               <android.support.design.widget.TextInputLayout
                    android:id="@+id/til_description"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="8dp"
                    app:errorText="@{feedbackViewModel.descError}"
                    >

                    <EditText
                        style="@style/TextInputLayoutEditText"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:background="@drawable/desc_field_selector"
                        **android:paddingTop="10dp"**
                        **android:paddingBottom="7dp"**
                        android:gravity="top|left"
                        android:hint="@string/description"
                        android:inputType="textMultiLine"
                        android:lines="4"
                        android:onTextChanged="@{(text, start, before, count) -> feedbackViewModel.onDescriptionTextChanged(text)}"
                        android:scrollHorizontally="false"
                        android:scrollbarStyle="insideInset"
                        android:scrollbars="vertical"
                        android:text="@={feedbackViewModel.description}"/>

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

And android:background="@drawable/desc_field_selector" -

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/rectangle_blue_border_background"
          android:state_pressed="true"/>
    <item android:drawable="@drawable/rectangle_blue_border_background"
          android:state_enabled="true"
          android:state_focused="true"
          android:state_window_focused="true"/>
    <item android:drawable="@drawable/rectangle_black_border_background"/>
</selector>

Now the original shape (@drawable/rectangle_black_border_background) will be like -

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    **<item android:state_focused="false" android:top="5dp">**
        <shape>
            **<solid android:color="@android:color/transparent"/>**
            <stroke android:width="1dp" android:color="@android:color/secondary_text_light"/>
            <corners android:radius="5dp"/>
        </shape>
    </item>
</layer-list>

And the original shape (@drawable/rectangle_blue_border_background) will be like -

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    **<item android:state_focused="true" android:top="5dp">**
        <shape>
            **<solid android:color="@android:color/transparent"/>**
            <stroke android:width="@dimen/one_dip" android:color="@color/colorAccent"/>
            <corners android:radius="5dp"/>
        </shape>
    </item>
</layer-list>

Note- The ** lines are too important -

  1. paddingTop="10dp" and android:paddingBottom="7dp" -> will move the floating label up enough from the border shape otherwise it won't look well.
  2. android:top="5dp" - are important for moving floating label enough to rect shape.
  3. solid android:color="@android:color/transparent" - this solid shape color will be transparent so when error will occur you will see just a transparent color. Have a look -

**Note - ** change your padding value and top value from item and the solid color according to need (You can also remove solid color line also).

enter image description here

That's it :-) Happy coding +1