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
Другие вопросы по тегам