TextInputLayout.setError() оставляет пустое пространство после устранения ошибки

Недавно я использовал метод TextInputLayout и setError(). Проблема, которую я получаю, заключается в том, что, когда я очищаю ошибку, вызывая setError(null), она оставляет столько свободного места внизу.

Normal:

Обычный

С ошибкой:

с ошибкой

После устранения ошибки:

После устранения ошибки

Посмотрев на источник, я обнаружил, что они делают вид INVISIBLE вместо GONE

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

    updateLabelVisibility(true);
} }).start();

Мне интересно, почему это так? Как разрешить это, чтобы избежать пустого пространства?

Ответ 1

Проверьте документы для

public void setErrorEnabled (boolean enabled)

В нем говорится

Включена или нет функция ошибки в этом макете. Включение этой функции перед установкой сообщения об ошибке через setError (CharSequence), будет означать, что этот макет не изменится размер при отображении ошибки.

Хорошо, основываясь на этом, попробуйте установить setErrorEnabled(true) до setError() и установите setErrorEnabled(false) после setError(null).

Ответ 2

Метод setErrorEnabled(false) очистит дополнительное пространство, поэтому вызовите его после setError(null).

Ответ 3

Смотрите эту страницу. Google выпустит исправление в будущей версии библиотеки поддержки. В нем говорится:

Если вы хотите исправить это сейчас, вы можете расширить TextInputLayout и переопределить метод setErrorEnabled(), но я не могу гарантировать Обратная совместимость. Потому что его некоторая опасность изменить состояние в 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);
            }
        }
    }
}

Ответ 4

Не используйте setErrorEnabled(boolean), он просто не отображает ошибку со второго раза.

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);
        }
    }
}
}

Затем просто setError(errorMessage); или setError(null);

Ответ 5

Я создаю пользовательский вид, чтобы избежать повторного кода и переопределить метод setError.

    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);
        }

     }

Ответ 6

Следующий код работает отлично

    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) {

        }
    });

Ответ 7

Используя mTextInputLayout.setErrorEnabled(false);, я решил эту проблему

Ответ 8

Затем вы должны переопределить его так:

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

    updateLabelVisibility(true); 
}

Или попробуйте это, например, на кнопке или в любом месте, которое вы используете:

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