TextInputLayout.setError() оставляет пустое пространство после очистки ошибки
Я недавно использовал TextInputLayout
И его setError()
метод. Проблема, которую я получаю, состоит в том, когда я устраняю ошибку, вызывая setError(null)
он оставляет так много пустого пространства внизу.
Нормальный:
С ошибкой:
После устранения ошибки:
Посмотрев на источник, я обнаружил, что они делают вид 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()
и установить setErrorEnabled(false)
после setError(null)
,
Метод setErrorEnabled(false)
очистит лишнее пространство, поэтому назовите его после setError(null)
,
Не использовать 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);
}
}
Это расширение в проблеме решения котлина:
fun TextInputLayout.clearError() {
error = null
isErrorEnabled = false
}
Исходный код TextInputLayout показывает следующее: Если вам нужно устранить ошибку, просто используйте
til.setErrorEnabled(false);
Это позволит скрыть текст ошибки и растянуть нижнее пространство до стандартного размера.
Если вам нужно снова установить ошибку, просто используйте
til.setError("Your text");
который автоматически вызывает til.setErrorEnabled(true)
так как предполагается, что вам нужна функциональность ошибок.
Смотрите эту страницу. 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); } } } }
Используя mTextInputLayout.setErrorEnabled(false);
я решил эту проблему
Следующий код работает нормально
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) {
}
});
Тогда вы должны переопределить это так:
@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