TextInputLayout.setError() leaves empty space after clearing the error

AndroidAndroid Textinputlayout

Android Problem Overview


I recently used TextInputLayout and it's setError() method. The problem I'm getting is, when I clear the error by calling setError(null) it leaves so much of empty space at the bottom.

Normal:

Normal

With error:

With error

After clearing error:

After clearing error

After looking at the source, I found that they are making the view INVISIBLE instead of GONE

> .setListener(new ViewPropertyAnimatorListenerAdapter() { > @Override > public void onAnimationEnd(View view) { > view.setVisibility(INVISIBLE); // here it is > > updateLabelVisibility(true); > } }).start();

I'm wondering why is it so? How to resolve this to avoid the empty space?

Android Solutions


Solution 1 - Android

Check out the docs for

public void setErrorEnabled (boolean enabled)

It says > Whether the error functionality is enabled or not in this layout. > Enabling this functionality before setting an error message via > setError(CharSequence), will mean that this layout will not change > size when an error is displayed.

Well based on this, try setting setErrorEnabled(true) before setError(), and, set setErrorEnabled(false) after setError(null).

Solution 2 - Android

Method setErrorEnabled(false) will clear the extra space, so call it after setError(null).

Solution 3 - Android

Dont use setErrorEnabled(boolean), it just doesnt show up the error from the second time.

public class MyTextInputLayout extends android.support.design.widget.TextInputLayout {

public MyTextInputLayout(Context context) {
    super(context);
}

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

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

@Override
public void setError(@Nullable CharSequence error) {
    super.setError(error);

    View layout = getChildAt(1);
    if (layout != null) {
        if (error != null && !"".equals(error.toString().trim())) {
            layout.setVisibility(VISIBLE);
        } else {
            layout.setVisibility(GONE);
        }
    }
}
}

Then just setError(errorMessage); or setError(null);

Solution 4 - Android

See this page. Google will release the fix in future support library version. It says,

> If you want to fix it now you can extends the TextInputLayout and > override the setErrorEnabled() method, but I cant guarantee the > backward compatibility. Because its some danger to change state in > TextInputLayout. > > public class TextInputLayout extends android.support.design.widget.TextInputLayout{ > > > public TextInputLayout(Context context) { > super(context); > } > > public TextInputLayout(Context context, AttributeSet attrs) { > super(context, attrs); > } > > public TextInputLayout(Context context, AttributeSet attrs, int defStyleAttr) { > super(context, attrs, defStyleAttr); > } > > @Override > public void setErrorEnabled(boolean enabled) { > super.setErrorEnabled(enabled); > if (enabled) { > return; > } > if (getChildCount() > 1) { > View view = getChildAt(1); > if (view != null) { > view.setVisibility(View.GONE); > } > } > } > }

Solution 5 - Android

The source code of TextInputLayout show the following: If you need to clear the error, just use

til.setErrorEnabled(false);

This will hide the error text and stretch the bottom space to its standard size.

In case you need to set the error again, just use

til.setError("Your text");

which automatically calls til.setErrorEnabled(true) as it assumes you need the error functionality.

Solution 6 - Android

I create a custom view for avoiding repeated code and override setError method.

    public class UserInputView extends TextInputLayout {

        public UserInputView(Context context) {
           this(context, null);
        }

        public UserInputView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }

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

        @Override
        public void setError(@Nullable CharSequence error) {
            boolean isErrorEnabled = error != null;
            setErrorEnabled(isErrorEnabled);
            super.setError(error);
        }

     }

Solution 7 - Android

This is extension in kotlin solving problem:

fun TextInputLayout.clearError() {
    error = null
    isErrorEnabled = false
}

Solution 8 - Android

The following code works fine

    textInputLatout.getEditText().addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            if (s.length() < 1) {
               textInputLayout.setErrorEnabled(true);
                textInputLayout.setError("Please enter a value");
		    }
  
            if (s.length() > 0) {
                textInputLayout.setError(null);
                textInputLayout.setErrorEnabled(false);
            }

        }

        @Override
        public void afterTextChanged(Editable s) {

        }
    });

Solution 9 - Android

By using mTextInputLayout.setErrorEnabled(false); i have solved this problem

Solution 10 - Android

Then you should override it like so:

@Override
public void onAnimationEnd(View view)
{
    view.setVisibility(GONE); // <-- this is where you make it GONE

    updateLabelVisibility(true); 
}

Or try this i.e. on a button or whatever you are using:

final Button btn = (Button) findViewById(R.id.btn);
btn.setVisibility(View.GONE); //<--- makes the button gone

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMangeshView Question on Stackoverflow
Solution 1 - AndroidharshitpthkView Answer on Stackoverflow
Solution 2 - AndroidMike MarguliesView Answer on Stackoverflow
Solution 3 - AndroidNeelaView Answer on Stackoverflow
Solution 4 - AndroidShaode LuView Answer on Stackoverflow
Solution 5 - AndroidromariomkkView Answer on Stackoverflow
Solution 6 - AndroidRahulView Answer on Stackoverflow
Solution 7 - AndroidRenetikView Answer on Stackoverflow
Solution 8 - AndroidGowsik K CView Answer on Stackoverflow
Solution 9 - AndroidRohit SharmaView Answer on Stackoverflow
Solution 10 - AndroidsuperkytozView Answer on Stackoverflow