70

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

普通的:

普通的

有错误:

有错误

清除错误后:

清除错误后

查看源代码后,我发现他们正在制作视图INVISIBLE而不是GONE

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

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

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

4

10 回答 10

158

查看文档

public void setErrorEnabled (boolean enabled)

它说

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

那么基于此,尝试设置setErrorEnabled(true)before setError(),然后设置setErrorEnabled(false)after setError(null)

于 2015-12-12T17:57:48.823 回答
53

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

于 2016-01-22T21:47:03.187 回答
5

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

于 2016-07-02T15:18:20.793 回答
4

请参阅页面。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);
            }
        }
    }
}
于 2016-01-11T14:14:29.210 回答
3

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

     }
于 2017-04-16T06:09:43.000 回答
3

TextInputLayout 的源代码如下: 如果需要清除错误,只需使用

til.setErrorEnabled(false);

这将隐藏错误文本并将底部空间拉伸到其标准大小。

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

til.setError("Your text");

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

于 2018-03-16T14:51:55.417 回答
2

这是 kotlin 解决问题的扩展:

fun TextInputLayout.clearError() {
    error = null
    isErrorEnabled = false
}
于 2020-06-30T20:33:57.477 回答
0

以下代码工作正常

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

        }
    });
于 2016-06-01T11:08:26.650 回答
0

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

于 2017-02-06T08:22:44.907 回答
-3

然后你应该像这样覆盖它:

@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
于 2015-12-12T17:52:38.850 回答