How can I set a custom error background for TextInputLayout

Viewed 475

I want to display a custom error background for my email input field whenever I have an invalid email.

So far all I could find was how to set and customise the error text, which also gave it a reddish background tint.

I have been trying with no avail to change this background to what I expect.

This is my layout

 <com.google.android.material.textfield.TextInputLayout
            android:id="@+id/email_field"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="24dp"
            android:layout_marginTop="24dp"
            android:layout_marginEnd="24dp"
            android:elevation="2dp"
            app:boxBackgroundMode="none"
            app:errorEnabled="true"
            app:hintEnabled="false"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/textView">

            <EditText
                android:id="@+id/input_email"
                android:layout_width="match_parent"
                android:layout_height="48dp"
                android:background="@drawable/input_field"
                android:drawableStart="@drawable/ic_baseline_account_circle_24"
                android:drawablePadding="8dp"
                android:fontFamily="@font/app_font_regular"
                android:hint="@string/label_email"
                android:imeOptions="actionNext"
                android:inputType="textEmailAddress"
                android:maxLines="1"
                android:padding="8dp"
                android:textColor="@color/textColor" />
        </com.google.android.material.textfield.TextInputLayout>

This is my input_field drawble

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_focused="true">
        <shape android:shape="rectangle">
            <corners android:radius="8dp" />
            <stroke android:width="1dp" android:color="@color/colorPrimary" />
            <solid android:color="@color/inputField" />
        </shape>
    </item>

    <item android:state_checked="true"  >
        <shape android:shape="rectangle">
            <corners android:radius="8dp" />
            <stroke android:width="1dp" android:color="@color/failed" />
            <solid android:color="@color/inputField" />
        </shape>
    </item>

    <item>
        <shape android:shape="rectangle">
            <corners android:radius="8dp" />
            <stroke android:width="1dp" android:color="@color/inputFieldBorder" />
            <solid android:color="@color/inputField" />
        </shape>
    </item>
</selector>

To display an error I use this method call on TextInputLayout

email_field.error = "Invalid Email"

This is my UI without an error My UI without an error

This is My UI when I set error My UI when I set error

This is the UI I'm hoping to achieve. enter image description here

2 Answers

You can use app:boxStrokeColor

<com.google.android.material.textfield.TextInputLayout
        ...
        app:boxBackgroundColor="@color/colorWhite"
        app:boxStrokeColor="@color/colorRed">
 ...
</com.google.android.material.textfield.TextInputLayout>

You don't need to use android:background="@drawable/input_field".

Just use:

        <com.google.android.material.textfield.TextInputLayout
            style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
            app:placeholderText="Email"
            app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.App.rounded8dp"
            app:boxStrokeErrorColor="@color/..."
            app:boxStrokeColor=""
            app:startIconDrawable="@drawable/...">

            <com.google.android.material.textfield.TextInputEditText
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                />

        </com.google.android.material.textfield.TextInputLayout>

with:

<style name="ShapeAppearanceOverlay.App.rounded8dp" parent="">
    <item name="cornerSize">8dp</item>
</style>

With the

  • app:boxStrokeColor define the selector for the stroke
  • app:boxStrokeErrorColor define the color used by the stroke when an error is shown.

The default value for the boxStrokeColor is:

You can use a selector. It is the default value:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:color="?attr/colorPrimary" android:state_focused="true"/>
  <item android:alpha="0.87" android:color="?attr/colorOnSurface" android:state_hovered="true"/>
  <item android:alpha="0.12" android:color="?attr/colorOnSurface" android:state_enabled="false"/>
  <item android:alpha="0.38" android:color="?attr/colorOnSurface"/>
</selector>

enter image description here

Related