ibrahimyilmaz
ibrahimyilmaz

Reputation: 18929

How to write style to error text of EditText in android?

I'm trying to write new custom style for my android application. I need to give style to errorText which appears after setting setError in EditText.

How can I customize style of it?

For example: I want to set its background white and textColor: Blue etc etc. in style.xml

enter image description here

Upvotes: 50

Views: 64203

Answers (7)

batsheva
batsheva

Reputation: 2295

follow this link to have a nice material design look of error message! materialdoc screenshot

I see the link is not working anymore so here is how to do it: use TextInputLayout

<android.support.design.widget.TextInputLayout
                android:id="@+id/ipAddress"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="-30dp"
                android:layout_gravity="end"
                android:digits="1234567890"
                app:errorEnabled="true" >
                <android.support.design.widget.TextInputEditText
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="end"
                    android:maxLines="1"
                    android:width="200dp"
                    android:text="@{ethernetData.ipAddress}"
                    android:enabled="@{!ethernetData.ethernetAutoIp}"/>

and in code in TextWatcher (I use data binding) call setError on your TextInputLayout

binding.ipAddress.setError(your error);

this is how i did it:

binding.ipAddress.getEditText().addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

        }

        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

        }

        @Override
        public void afterTextChanged(Editable editable) {

            if(! Patterns.IP_ADDRESS.matcher(editable.toString()).matches()) {
                binding.ipAddress.setError(your error string);
                IpAddressOK = false;
            }
            else{
                binding.ipAddress.setError(null);
                IpAddressOK = true;
            }
        }
    });

Upvotes: 2

Milszym
Milszym

Reputation: 386

I have not found any solution to edit error style, but I have created custom EditText with error popup. Hopefully, it will help:


import android.content.Context
import android.util.AttributeSet
import android.view.Gravity
import android.view.LayoutInflater
import android.widget.EditText
import android.widget.LinearLayout
import android.widget.PopupWindow
import android.widget.TextView
import androidx.annotation.StringRes

class ErrorEditText : EditText {

    constructor(context: Context) : super(context)

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs)

    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)

    private var errorPopup: PopupWindow? = null

    fun showError(message: String) {
        showErrorPopup(message)
    }

    fun showError(@StringRes messageResId: Int) {
        showErrorPopup(context.getString(messageResId))
    }

    fun dismissError() {
        post {errorPopup?.dismiss() }
    }

      private fun showErrorPopup(message: String) {
        post {
            dismissError()
            val inflater = (context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater)
            val view = inflater.inflate(R.layout.edit_text_error, null, false)
            errorPopup =
                PopupWindow(view, LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT)
            errorPopup?.contentView?.findViewById<TextView>(R.id.message)?.text = message
            errorPopup?.showAsDropDown(this, 0, 10, Gravity.START)
        }
    }
}

You can use methods: showError(message: String) or showError(@StringRes messageResId: String) to show the error and method dismissError() to hide it.

Keep in mind that pop-ups are bound with activity lifecycle if you are using multiple fragments to navigate through the app, remember about closing them when navigating.

Here is my edit_text_error layout used for popup:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="2dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        android:elevation="2dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:background="#fff">

        <TextView
            android:id="@+id/message"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#E20000"
            android:padding="8dp"
            android:textSize="11sp"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            tools:text="Please enter a valid email address!" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

If you'd like to move popup to the end of EditText, please change last line in showErrorPopup() method to: errorPopup?.showAsDropDown(this, 0, 10, Gravity.END)

You can manipulate the position of the popup by modifying gravity or x and y parameters of the showAsDropDown(view: View, x: Int, y: Int, gravity: Gravity) method

Upvotes: 0

Emmanuelguther
Emmanuelguther

Reputation: 1059

This works fine!

private fun setErrorOnSearchView(searchView: SearchView, errorMessage: 
String) {
val id = searchView.context
        .resources
        .getIdentifier("android:id/search_src_text", null, null)
val editText = searchView.find<EditText>(id)

val errorColor = ContextCompat.getColor(this,R.color.red)
val fgcspan = ForegroundColorSpan(errorColor)
val builder = SpannableStringBuilder(errorMessage)
builder.setSpan(fgcspan, 0, errorMessage.length, 0)
editText.error = builder
}

Upvotes: 0

Daniele Segato
Daniele Segato

Reputation: 12909

I've seen the accepted answer but i don't like the proposed library

I think this is a bug in the Android framework and I filed a bug here: https://code.google.com/p/android/issues/detail?id=158590

EDIT: the android design library TextInputLayout widget can be used to obtain a better error handling on EditText.

See how it looks like here: https://www.youtube.com/watch?v=YnQHb0fNtF8

And how to implement here: http://code.tutsplus.com/tutorials/creating-a-login-screen-using-textinputlayout--cms-24168

Upvotes: 4

Sachin Arora
Sachin Arora

Reputation: 436

Please add it at the time of form validation if edit text field is blank.

            int ecolor = R.color.black; // whatever color you want
        String estring = "Please enter a valid email address";
        ForegroundColorSpan fgcspan = new ForegroundColorSpan(ecolor);
        SpannableStringBuilder ssbuilder = new SpannableStringBuilder(estring);
        ssbuilder.setSpan(fgcspan, 0, estring.length(), 0);

        edtEmail.requestFocus();
        edtEmail.setError(ssbuilder); 

when you write in edit text, error sign automatic goes off

Thanks Sachin

Upvotes: 10

Sherif elKhatib
Sherif elKhatib

Reputation: 45942

The solution is at the end and here is the screenshot:

Styled error


Some Explanation

You might be able to set the textcolor using the following line

yourEditText.setError(Html.fromHtml("<font color='blue'>this is the error</font>"));

However, this might not be guaranteed.


According to the source code, this Popup that shows is of type ErrorPopup which is an internal class inside TextView. The content of this Popup is a single TextView inflated from com.android.internal.R.layout.textview_hint

final TextView err = (TextView) inflater.inflate(com.android.internal.R.layout.textview_hint,
      null);

The background of this Popup depends on whether it should be placed above the anchor:

if (above) {
    mView.setBackgroundResource(com.android.internal.R.drawable.popup_inline_error_above);
} else {
    mView.setBackgroundResource(com.android.internal.R.drawable.popup_inline_error);
}

Since all the android resources used to create the popup are internal and ultimately hard-coded, your best shot would be to create your own error popup. This would be very easy and you wouldn't really be interfering with the normal EditText because the default popup is merely used to show the error, and, thus, creating your own would be fine.


SOLUTION

I have created it here: WidgyWidgets

Upvotes: 31

Dheeraj Vepakomma
Dheeraj Vepakomma

Reputation: 28767

I don't think you can customize its style that way since the error popup uses an internal style:

mPopupInlineErrorBackgroundId = getResourceId(mPopupInlineErrorBackgroundId,
                    com.android.internal.R.styleable.Theme_errorMessageBackground);
mView.setBackgroundResource(mPopupInlineErrorBackgroundId);

However, you can set a Spanned and a custom error icon using the overloaded setError(CharSequence, Drawable).

You can easily create a Spanned from HTML using fromHtml().

However, you still won't be able to set the popup background image :-(

Upvotes: 21

Related Questions