34

What I want to do is change the background color (set custom drawable) of a popup error message displayed after using setError() method.

Currently, it looks like this:

enter image description here

I've found that Android has two files:

  • popup_inline_error.9.png
  • popup_inline_above_error.9.png

And you're supposed to be able to set them using two attributes:

  • errorMessageBackground
  • errorMessageAboveBackground

But when I try to set them in my theme, all I get is:

<item name="errorMessageBackground">@drawable/popup_inline_error_holo_light</item>
<item name="errorMessageAboveBackground">@drawable/popup_inline_error_above_holo_light</item>

error: Error: No resource found that matches the given name: attr 'errorMessageBackground'.

(it's the same with android:errorMessageBackground)

I'm putting this question here, cause I've run out of ideas - maybe someone already managed to do that?

EDIT: Header of the Theme I'm using:

<resources xmlns:android="http://schemas.android.com/apk/res/android">
    <style
        name="Theme.MyThemeName"
        parent="@style/Theme.Sherlock.Light">

ANOTHER EDIT: Uh, I've found that my question is a duplicate of: android:errorMessageBackground getting no resource found error in styles.xml

YET ANOTHER EDIT: This is a known problem, take a look at this link: https://code.google.com/p/android/issues/detail?id=55879

Community
  • 1
  • 1
scana
  • 2,785
  • 2
  • 25
  • 49
  • 1
    Have you taken a look at [this question](http://stackoverflow.com/questions/6745577/which-theme-attribute-changes-the-text-color-of-an-edittexts-error-message)? – Cat Jan 02 '13 at 19:23
  • 1
    I did, actually - but I want to change the color of the bubble, not the text color (which I'm able to change). I've noticed that Chris managed to change the background - I have no idea how. – scana Jan 02 '13 at 19:35
  • It seems that `errorMessageBackground` is a new attribute introduced in Android API level 19. Have you try to put your style into `values-v19` folder? – Hieu Rocker Jun 15 '14 at 15:42
  • @scana Did you manage to solve it? Please do answer your question. That would help many. – Shobhit Puri Aug 14 '14 at 06:35
  • @ShobhitPuri Sorry, I did not - I've decided to write my own error display system back then. But why don't you try and take a look at this project: https://github.com/sherifelkhatib/WidgyWidgets – scana Aug 14 '14 at 10:16
  • 2
    The original issue, cited in the last question edit, was erroneously marked as obsolete. I have [reopened the issue](https://code.google.com/p/android/issues/detail?id=133504). I know of no workaround, other than to not use `setError()` and do something else. – CommonsWare Feb 04 '15 at 15:31
  • Check this link http://stackoverflow.com/questions/14413575/how-to-write-style-to-error-text-of-edittext-in-android – Samir Bhatt Oct 14 '15 at 13:01

4 Answers4

10

I would suggest to use @Codeversed solution, but if it doesn't fit for you for some reason you can use my custom EditText implementation.

Usual EditText representation: enter image description here

EditText with error: enter image description here

In few words: I've created custom xml state for error display. See related code below:

InputEditText.java:

import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.widget.EditText;

import com.example.oleksandr.inputedittext.R;

/**
 * Input EditText which allows define custom drawable for error state
 */
public class InputEditText extends EditText {

    private static final int[] STATE_ERROR = {R.attr.state_error};

    private boolean mIsError = false;

    public InputEditText(Context context) {
        this(context, null, 0);
        init();
    }

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

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

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public InputEditText(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init();
    }

    private void init() {
        addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                // empty
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                setError(null);
            }

            @Override
            public void afterTextChanged(Editable s) {
                // empty
            }
        });
    }

    @Override
    public void setError(CharSequence error) {
        mIsError = error != null;
        super.setError(error);
        refreshDrawableState();
    }

    @Override
    public void setError(CharSequence error, Drawable icon) {
        mIsError = error != null;
        super.setError(error, icon);
        refreshDrawableState();
    }

    @Override
    protected int[] onCreateDrawableState(int extraSpace) {
        final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
        if (mIsError) {
            mergeDrawableStates(drawableState, STATE_ERROR);
        }
        return drawableState;
    }
}

drawable/edittext_bg_error.xml

<?xml version="1.0" encoding="utf-8"?>
<shape
    android:id="@+id/listview_background_shape"
    xmlns:android="http://schemas.android.com/apk/res/android"
    >
    <stroke
        android:width="2dp"
        android:color="#f00"
        />
    <padding
        android:bottom="2dp"
        android:left="2dp"
        android:right="2dp"
        android:top="2dp"
        />
    <corners android:radius="5dp"/>
    <solid android:color="#ffffffff"/>
</shape>

drawable/edittext_bg_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <!-- custom error state drawable -->
    <item android:drawable="@drawable/edittext_bg_error" app:state_error="true"/>

    <!-- Do whatever you want for all other states -->
    <item android:drawable="@android:drawable/editbox_background_normal"/>
</selector>

add to your attrs.xml

<attr name="errorColor" format="reference"/>

and to styleables.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="error">
        <attr name="state_error" format="boolean"/>
    </declare-styleable>
</resources>

and usage is really simple:

<com.example.oleksandr.inputedittext.views.InputEditText
    android:id="@id/edittext"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/edittext_bg_selector"
    android:inputType="text"
    android:text="@string/hello_world"
    />

[EDIT]:

Just realized, that original answer was about changing error popup color, but not EditText background color. Anyway, hope this can help someone.

Community
  • 1
  • 1
Oleksandr
  • 6,226
  • 1
  • 46
  • 54
5

you will need to include these dependancies:

compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.android.support:design:23.1.1'

and here is a sample on how to use it:

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

        <EditText
            android:id="@+id/input_password"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/hint_email" />

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

This will give you the Material Design you are looking for to give form validation as well as a nice animation effect for the label.

enter image description here

Codeversed
  • 9,287
  • 3
  • 43
  • 42
-1
private EditText adTitle;
// ....
adTitle.setError(Html.fromHtml("<font color='red'>hello</font>"));
user2131854
  • 137
  • 4
-2

You can use this method just pass msg text,your edittext id

 public static void setErrorMsg(String msg,EditText viewId)
{
    //Osama ibrahim 10/5/2013
    int ecolor = Color.WHITE; // whatever color you want
    String estring = msg;
    ForegroundColorSpan fgcspan = new ForegroundColorSpan(ecolor);
    SpannableStringBuilder ssbuilder = new SpannableStringBuilder(estring);
    ssbuilder.setSpan(fgcspan, 0, estring.length(), 0);
    viewId.setError(ssbuilder);

}
Osama Ibrahim
  • 995
  • 10
  • 13
  • 3
    Sorry, that is not what I wanted - I had to change the whole background, to make it look the same as error message from ICS. – scana Jul 09 '13 at 13:13