19

I have a vertical linear layout with some input fields. Using TextInputLayout I get a nice flow with labels and built-in error messages. My problem is when I add and remove the error-messages.

If I add an error message it is positioned below the edit-text and everything looks good.

If I remove the error message with setError(null) the message is removed but the space is still there. This is per googles design apparently(see https://code.google.com/p/android/issues/detail?id=176005). I would very much like this space removed as it makes the UI look very wrong.

If I do .setErrorEnabled(false) the view is removed and everything looks normal again. However if the user changes the data and I do another setError the error-message is not shown (only the edit text line is red).

Gober
  • 3,632
  • 3
  • 26
  • 33

3 Answers3

33

As of Support library version 23.1.1 (and perhaps earlier), this should no longer be the case. You should be able to call TextInputLayout.setErrorEnabled(false) to hide the error TextView and calling TextInputLayout.setError(error) now internally calls TextInputLayout.setErrorEnabled(true) if the error isn't null or empty. See the code snippet below, taken from the support library:

public void setError(@Nullable CharSequence error) {
    if (!mErrorEnabled) {
        if (TextUtils.isEmpty(error)) {
            // If error isn't enabled, and the error is empty, just return
            return;
        }
        // Else, we'll assume that they want to enable the error functionality
        setErrorEnabled(true);
    }
    ...
}
TheIT
  • 11,919
  • 4
  • 64
  • 56
  • 1
    Thank you. This works better now. Previously I looked for children of TextInputLayout and set visibility to gone. Now you can simply do input.setError(..) for new error and input.setErrorEnabled(false) to remove it. Works back and forth. Would still be nice to just do input.setError(null) but you can't have it all. – Gober Feb 04 '16 at 12:53
  • 3
    In my case, I had to do both input.setError(null) & input.setErrorEnabled(false) for it to work properly. – User31689 Mar 25 '16 at 22:45
  • 1
    Unfortunately it does not work for version 23.2.1. If you look at the very beginning of the method, it returns if provided error string was previously set: if (TextUtils.equals(mError, error)) { // If we already have the same error, ignore return; } – Singed May 17 '16 at 14:18
7

For me, below code is working fine.

@Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        if(mobileNoInputLayout.isErrorEnabled()){
            mobileNoInputLayout.setErrorEnabled(false);
        }
    }
Arul Pandian
  • 1,685
  • 15
  • 20
1

I created a Kotlin extension for this:

var TextInputLayout.errorMessage: CharSequence?
    get() = error
    set(errorMessage) = setErrorMessage(errorMessage)

@JvmName("setErrorMessageWithTogglingErrorEnabled")
fun TextInputLayout.setErrorMessage(errorMessage: CharSequence?) {
    error = errorMessage
    isErrorEnabled = !errorMessage.isNullOrEmpty()
}

To show the error message:

binding.field.errorMessage = "An error message"

To remove the error message:

binding.field.errorMessage = null
OzgurG
  • 1,634
  • 1
  • 16
  • 21