清除错误后 TextInputLayout.setError() 留空 space

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

我最近使用了 TextInputLayout 并且是 setError() 方法。我遇到的问题是,当我通过调用 setError(null) 清除错误时,它在底部留下了很多空的 space。

正常:

有错误:

清除错误后:

看了源码,发现他们做的view是INVISIBLE而不是GONE

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

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

我想知道为什么会这样?如何解决这个问题以避免空 space?

那么你应该像这样覆盖它:

@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

查看

的文档
public void setErrorEnabled (boolean enabled)

它说

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.

基于此,尝试在setError()之前设置setErrorEnabled(true),在setError(null)之后设置setErrorEnabled(false)

参见 this 页。 Google 将在未来的支持库版本中发布修复程序。它说,

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

方法setErrorEnabled(false)会清除多余的space,所以在setError(null)之后调用。

下面的代码工作正常

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

        }
    });

不要使用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);

通过使用mTextInputLayout.setErrorEnabled(false);我已经解决了这个问题

我创建了一个自定义视图以避免重复代码并覆盖 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);

这将隐藏错误文本并将底部 space 拉伸至标准尺寸。

如果您需要再次设置错误,只需使用

til.setError("Your text");

它会自动调用 til.setErrorEnabled(true),因为它假设您需要错误功能。

这是kotlin解决问题的扩展:

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