188

I need an EditText that looks like this onError:

enter image description here

calling onError looks like this instead :

enter image description here

Note: the app is running on SDK 19 (4.4.2)

min SDK is 1

Is there a method similar to setError that does this automatically, or do I have to write the code for it ?

Thank you

kmn
  • 2,615
  • 4
  • 18
  • 28
  • 1
    You are unlikely to be able to do that with just an `EditText`. More likely, you will need something that wraps `EditText` or otherwise adds to it. See https://github.com/rengwuxian/MaterialEditText. – CommonsWare Jun 20 '15 at 11:31

7 Answers7

376

There's no need to use a third-party library since Google introduced the TextInputLayout as part of the design-support-library.

Following a basic example:

Layout

<android.support.design.widget.TextInputLayout
    android:id="@+id/text_input_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:errorEnabled="true">

    <android.support.design.widget.TextInputEditText
        android:id="@+id/edit_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Enter your name" />

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

Note: By setting app:errorEnabled="true" as an attribute of the TextInputLayout it won't change it's size once an error is displayed - so it basically blocks the space.

Code

In order to show the Error below the EditText you simply need to call #setError on the TextInputLayout (NOT on the child EditText):

TextInputLayout til = (TextInputLayout) findViewById(R.id.text_input_layout);
til.setError("You need to enter a name");

Result

picture showing the edit text with the error message

To hide the error and reset the tint simply call til.setError(null).


Note

In order to use the TextInputLayout you have to add the following to your build.gradle dependencies:

dependencies {
    compile 'com.android.support:design:25.1.0'
}

Setting a custom color

By default the line of the EditText will be red. If you need to display a different color you can use the following code as soon as you call setError.

editText.getBackground().setColorFilter(getResources().getColor(R.color.red_500_primary), PorterDuff.Mode.SRC_ATOP);

To clear it simply call the clearColorFilter function, like this:

editText.getBackground().clearColorFilter();
MontDeska
  • 1,617
  • 19
  • 16
reVerse
  • 35,075
  • 22
  • 89
  • 84
  • 3
    Yes ! That's it ! How do you make the line red though ? – kmn Jun 20 '15 at 12:36
  • 1
    How can I customise the TextInputLayout ? (suppose I wanted to move 'Enter your name' to the left and change the Line colors, etc...), Android's documentation doesn't say much (https://developer.android.com/reference/android/support/design/widget/TextInputLayout.html). You don't have to show me how to do everything, but could you please point me to a good reference doc ? – kmn Jun 20 '15 at 12:39
  • 3
    @kmn Making the line red doesn't come out of the box so you need to do it on your own. See my edit. In terms of moving the Hint: That's afaik not possible. – reVerse Jun 20 '15 at 12:46
  • Interesting thing is no need to setErrorEnabled(true). when you implement seterror method to non-null string, setErrorEnabled(true) called automatically. – David Aug 30 '15 at 14:16
  • @reVerse after setting the line to red, how do I remove the red line? I tried `editText.getBackground().clearColorFilter(); editText.invalidate()` but it's not working – You Qi Oct 12 '15 at 07:51
  • @reVerse your solution works very well, but only if your activity extends the Activity class; it doesn't work instead if your activity extends the AppCompatActivity class. – Alessio Nov 16 '15 at 10:23
  • @Alessio That's more or less unlikely since every activity has to extend `AppCompatActivity` in order to "use" the appcompat "functionality". – reVerse Nov 16 '15 at 10:47
  • @reVerse not so sure what do you exactly mean by "use the appcompat functionality" as I had your set up working extending Activity, with an EditText wrapped by TextInputLayout provided by Support Design 23.1.0. The problem was on 4.4.4 once extending AppCompatActivity instead, setting the bottom line color via editText.getBackground().setColorFilter() didn't work anymore. I found a workaround in that case defining app:theme for the TextInputLayout, and there I have: which controls the bottom 'normal' color. – Alessio Nov 16 '15 at 11:29
  • 5
    @Alessio I've been just trying to say that it should work when you're extending AppCompatActivity. Nevertheless: As of appcompat-v23 it's not necessary to set the colorFilter anymore, as soon as you're calling `textInputLayout.setError("Error messsage")` the color of the `EditText` should turn red. In order to reset it, it's enough to call `textInputLayout.setError(null)`. – reVerse Nov 16 '15 at 12:12
  • @reVerse and I've been just trying to tell you that setting the bottom line (not the text) color as you explain works only and only if you extend Activity, but it doesn't work for AppCompatActivity. Also, in my case the red is my primary color, so I need to set the error color to another color but red, so for me I still have that need. – Alessio Nov 17 '15 at 10:16
  • 3
    `editText.getBackground().setColorFilter(getResources().getColor(R.color.red_500_primary), PorterDuff.Mode.SRC_ATOP);` is not needed anymore with the latest support library – Antoine Mar 23 '16 at 09:51
  • 18
    Just wanted to note, since it's such a small detail - I was having this problem by calling setError on the `EditText`, not the `TextInputLayout`. I saw this answer and still couldn't figure out what I needed to change. Very easy thing to miss. – h_k Jul 28 '16 at 18:12
  • One disadvantage of attaching the error message to the TextInputLayout is that it requires more vertical layout space. In my case, it would be nice to have an easy way to modify the background color of the EditText error message from black. Anyone have a simple solution? – GregM Jan 31 '17 at 19:48
  • great post. is there support for variable error message ? – RonTLV Dec 04 '18 at 15:07
  • @RonTLV Can you elaborate what you mean with "variable error message"? – reVerse Dec 04 '18 at 16:17
  • What would you do when trying to use this for an EditTextPreference? – jonasxd360 Feb 17 '19 at 19:59
  • Important: You have to `mutate` the `ColorFilter`, otherwise it'll mess with other text fields too! – Neph Mar 26 '20 at 12:23
  • The issue with that layout changing it's size is when you use it in tablerows, for example when you want to have a button below with the same height, that error being shown outside the editText breaks my solution. – David Jul 13 '22 at 21:00
  • @David Setting `app:errorEnabled="true"` didn't work for you? – reVerse Jul 14 '22 at 18:25
13

Call myTextInputLayout.setError() instead of myEditText.setError().

These container and containment have double functionality on setting errors. Functionality you need is container's one. But you could require minimal version of 23 for that.

Zon
  • 18,610
  • 7
  • 91
  • 99
7

Your EditText should be wrapped in a TextInputLayout

<android.support.design.widget.TextInputLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/tilEmail">

    <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:inputType="textEmailAddress"
        android:ems="10"
        android:id="@+id/etEmail"
        android:hint="Email"
        android:layout_marginTop="10dp"
        />

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

To get an error message like you wanted, set error to TextInputLayout

TextInputLayout tilEmail = (TextInputLayout) findViewById(R.id.tilEmail);
if (error){
    tilEmail.setError("Invalid email id");    
}

You should add design support library dependency. Add this line in your gradle dependencies

compile 'com.android.support:design:22.2.0'
fawaad
  • 341
  • 6
  • 12
aqel
  • 415
  • 1
  • 5
  • 11
5

reVerse's answer is great but it didn't point out how to remove the floating error tooltip kind of thing

You'll need edittext.setError(null) to remove that.
Also, as someone pointed out, you don't need TextInputLayout.setErrorEnabled(true)

Layout

<android.support.design.widget.TextInputLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <EditText
        android:id="@+id/edittext"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Enter something" />
</android.support.design.widget.TextInputLayout>

Code

TextInputLayout til = (TextInputLayout) editText.getParent();
til.setError("Your input is not valid...");
editText.setError(null);
ericn
  • 12,476
  • 16
  • 84
  • 127
4

If anybody still facing the error with using google's design library as mentioned in the answer then, please use this as commented by @h_k which is -

Instead of calling setError on TextInputLayout, You might be using setError on EditText itself.

B.shruti
  • 1,589
  • 1
  • 21
  • 41
1
TextInputLayout til = (TextInputLayout)editText.getParent();
til.setErrorEnabled(true);
til.setError("some error..");
0
private EditText edt_firstName;
private String firstName;

edt_firstName = findViewById(R.id.edt_firstName);

private void validateData() {
 firstName = edt_firstName.getText().toString().trim();
 if (!firstName.isEmpty(){
//here api call for ....
}else{
if (firstName.isEmpty()) {
                edt_firstName.setError("Please Enter First Name");
                edt_firstName.requestFocus();
            } 
}
}
MEGHA DOBARIYA
  • 1,622
  • 9
  • 7
  • When answering an old question, your answer would be much more useful to other StackOverflow users if you included some context to explain how your answer helps, particularly for a question that already has an accepted answer. See: [How do I write a good answer](https://stackoverflow.com/help/how-to-answer). – David Buck Jan 27 '20 at 06:49