Android TextInputLayout.setError()在清除错误后留下空白

Android TextInputLayout.setError()在清除错误后留下空白,android,android-textinputlayout,Android,Android Textinputlayout,我最近使用了TextInputLayout,它是setError()方法。我遇到的问题是,当我通过调用setError(null)清除错误时,它在底部留下了大量的空白 正常: 有误: 清除错误后: 查看源代码后,我发现他们正在使视图不可见,而不是消失 我想知道为什么会这样?如何解决此问题以避免出现空白?那么您应该像这样覆盖它: @Override public void onAnimationEnd(View view) { view.setVisibility(GONE); //

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

正常:

有误:

清除错误后:

查看源代码后,我发现他们正在使视图
不可见
,而不是
消失


我想知道为什么会这样?如何解决此问题以避免出现空白?

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

@Override
public void onAnimationEnd(View view)
{
    view.setVisibility(GONE); // <-- this is where you make it GONE

    updateLabelVisibility(true); 
}
@覆盖
onAnimationEnd上的公共无效(视图)
{

view.setVisibility(GONE);//查看文档以了解更多信息

public void setErrorEnabled (boolean enabled)
上面说

此布局中是否启用了错误功能。 在通过设置错误消息之前启用此功能 setError(CharSequence)表示此布局不会更改 显示错误时的大小

基于此,请尝试在
setError()
之前设置
setErrorEnabled(true)
,并在
setError(null)
之后设置
setErrorEnabled(false)
参见第页。谷歌将在未来的支持库版本中发布此修复程序。它说

如果现在要修复它,可以扩展
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(false)
将清除多余的空间,因此在
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) {

        }
    });
textInputLaOut.getEditText().addTextChangedListener(新的TextWatcher(){
@凌驾
更改前文本之前的公共void(字符序列s、int start、int count、int after){
}
@凌驾
public void onTextChanged(字符序列、int start、int before、int count){
如果(s.长度()<1){
textInputLayout.setErrorEnabled(真);
textInputLayout.setError(“请输入一个值”);
}
如果(s.长度()>0){
textInputLayout.setError(null);
textInputLayout.setErrorEnabled(false);
}
}
@凌驾
公共无效后文本已更改(可编辑){
}
});

不要使用
setErrorEnabled(布尔值)
,它只是不会在第二次显示错误

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

然后通过使用
mtdeputLayout.setErrorEnabled(false);
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(false);
til.setError("Your text");

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

这是kotlin解决问题的扩展:

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

事实上,你是在为它制作自己的动画吗?抱歉,我不明白你在说什么。视图可以是任何类似于按钮的东西。你是对的。谢谢你指出这一点。但它仍然占用了很多空间,而且在预览布局时也不可预测。我仍然不明白他们为什么这么做。嗯,不是真的您知道他们为什么要这样实现吗?是的,拥有View.GONE会更好地节省空间,但如果它们位于TextInputLayout下方,并且必须向下移动,则可能会给一些复杂的视图组带来问题。在seterror上,它会展开。但是,将error设置为null或将settingErrorEnabled设置为false并不会使布局向后折叠。seterror calls setErrorEnabled(true)InternallyExcellent!我为此创建了两个扩展函数:fun TextInputLayout.batherRor(errorText:String){this.isErrorEnabled=true this.error=errorText}fun TextInputLayout.removeError(){this.isErrorEnabled=false this.error=null}@HRaval该错误已在支持库v23.2.0中修复,但我尚未验证it@ShaodeLu,我已经检查了23.3.0,他们没有修复它。这个响应给了我预期的结果。谢谢。谢谢。这正是我所需要的!为什么我们需要
setError(null)
?工作正常,但它会立即删除文本。有没有办法使其动画化?