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

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

нормальный:

Normal

ошибка:

With error

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

After clearing error

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

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

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

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

9 ответов


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

public void setErrorEnabled (boolean enabled)

Он говорит:

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

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


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


посмотреть этой страница. 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);
            }
        }
    }
}

Не используйте 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);


Я создаю пользовательский вид для избежания повторного кода и переопределения 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);
        }

     }

исходный код TextInputLayout показывает следующее: Если вам нужно очистить ошибку, просто используйте

til.setErrorEnabled(false);

это скроет текст ошибки и растянет нижнее пространство до его стандартного размера.

В случае, если вам нужно снова установить ошибку, просто используйте

til.setError("Your text");

который автоматически вызывает til.setErrorEnabled(true) поскольку предполагается, что вам нужна функциональность ошибки.


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

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

        }
    });

С помощью mTextInputLayout.setErrorEnabled(false); Я решил эту проблему


тогда вы должны переопределить его следующим образом:

@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