清除错误后,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(); 

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

查看文档

 public void setErrorEnabled (boolean enabled) 

它说

在此布局中是否启用错误function。 在通过setError(CharSequence)设置错误消息之前启用此function将意味着此布局在显示错误时不会更改大小。

基于此,尝试在setError() setErrorEnabled(true)之前设置setErrorEnabled(true) ,并在setError(null)之后设置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);

我创build一个自定义视图,以避免重复的代码和重写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); } } 

下面的代码工作正常

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

或者试试这个,即一个button或任何你正在使用:

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