按照Google的要求设计Android EditText以显示错误消息

189

我需要一个像这样 onError 的 EditText

enter image description here

调用 onError 时应该看起来像这样:

enter image description here

注意:应用程序正在运行 SDK 19 (4.4.2)

最小 SDK 是 1

是否有类似于 setError 自动执行此操作的方法,还是我必须编写代码?

谢谢


1
你很可能无法仅使用 EditText 来完成这个任务。更有可能的是,你需要一些包装 EditText 或者其他添加功能的东西。请参考 https://github.com/rengwuxian/MaterialEditText。 - CommonsWare
7个回答

378

自从Google推出了design-support-library,就不需要使用第三方库来实现TextInputLayout

以下是一个基本示例:

布局

<android.support.design.widget.TextInputLayout
    android:id="@+id/text_input_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:errorEnabled="true">

    <android.support.design.widget.TextInputEditText
        android:id="@+id/edit_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Enter your name" />

</android.support.design.widget.TextInputLayout>

注意:app:errorEnabled="true"设置为TextInputLayout的属性后,一旦显示错误,它的大小就不会改变,因此基本上会阻塞空间。

代码

为了在EditText下方显示错误,您只需要在TextInputLayout上调用#setError(而不是在子EditText上调用):

TextInputLayout til = (TextInputLayout) findViewById(R.id.text_input_layout);
til.setError("You need to enter a name");

结果

显示带有错误消息的编辑文本的图片

要隐藏错误并重置色调,只需调用til.setError(null)


注意

为了使用TextInputLayout,您必须将以下内容添加到build.gradle依赖项中:

dependencies {
    compile 'com.android.support:design:25.1.0'
}

设置自定义颜色

EditText 默认的下划线是红色的。如果你需要显示不同的颜色,你可以在调用 setError 方法之前使用以下代码:

editText.getBackground().setColorFilter(getResources().getColor(R.color.red_500_primary), PorterDuff.Mode.SRC_ATOP);

要清除它,只需调用clearColorFilter函数,像这样:

editText.getBackground().clearColorFilter();

3
好的!那就是它了!但是你怎么把这条线变成红色的呢? - kmn
3
把线变成红色并不是默认功能,所以你需要自己操作。请查看我的编辑。至于移动提示,据我所知是不可能的。 - reVerse
5
我理解您的意思是,当您扩展AppCompatActivity时,它应该能够正常工作。但是,自从appcompat-v23版本以来,不再需要设置colorFilter。只要调用textInputLayout.setError("Error messsage")EditText的颜色应该会变为红色。如果要将其重置,则只需调用textInputLayout.setError(null)即可。 - reVerse
3
最新的支持库不再需要editText.getBackground().setColorFilter(getResources().getColor(R.color.red_500_primary), PorterDuff.Mode.SRC_ATOP);这行代码了。 - Antoine
18
只想提一下,因为这是一个细节问题 - 我遇到这个问题是在 EditText 上调用了 setError 方法,而不是在 TextInputLayout 上。我看到了这个答案,但仍然无法弄清楚需要改变什么。这是一个非常容易被忽略的小错误。 - h_k
显示剩余14条评论

13

使用myTextInputLayout.setError()而不是myEditText.setError()

这些容器和包含具有设置错误的双重功能。您所需要的功能是容器的功能。但是,您可能需要23的最小版本。


7

你的EditText应该被包含在一个TextInputLayout中。

<android.support.design.widget.TextInputLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:id="@+id/tilEmail">

    <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:inputType="textEmailAddress"
        android:ems="10"
        android:id="@+id/etEmail"
        android:hint="Email"
        android:layout_marginTop="10dp"
        />

</android.support.design.widget.TextInputLayout>

为了获得您想要的错误消息,请将错误设置为 TextInputLayout
TextInputLayout tilEmail = (TextInputLayout) findViewById(R.id.tilEmail);
if (error){
    tilEmail.setError("Invalid email id");    
}

你需要添加设计支持库依赖项。请在Gradle依赖项中添加以下行:
compile 'com.android.support:design:22.2.0'

5

reVerse的回答很好,但没有指出如何删除浮动的错误工具提示。

您需要使用edittext.setError(null)来删除它。
另外,正如某人指出的那样,您不需要使用TextInputLayout.setErrorEnabled(true)

布局

<android.support.design.widget.TextInputLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <EditText
        android:id="@+id/edittext"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Enter something" />
</android.support.design.widget.TextInputLayout>

代码

TextInputLayout til = (TextInputLayout) editText.getParent();
til.setError("Your input is not valid...");
editText.setError(null);

4
如果您仍然遇到使用谷歌设计库时出现错误,如答案中所述,请按照@h_k的评论使用以下方法 -
不要在TextInputLayout上调用setError,而应该在EditText本身上调用setError。

1
TextInputLayout til = (TextInputLayout)editText.getParent();
til.setErrorEnabled(true);
til.setError("some error..");

7
无需使用setErrorEnabled。 - JacksOnF1re

0
private EditText edt_firstName;
private String firstName;

edt_firstName = findViewById(R.id.edt_firstName);

private void validateData() {
 firstName = edt_firstName.getText().toString().trim();
 if (!firstName.isEmpty(){
//here api call for ....
}else{
if (firstName.isEmpty()) {
                edt_firstName.setError("Please Enter First Name");
                edt_firstName.requestFocus();
            } 
}
}

当回答一个旧问题时,如果您包含一些上下文来解释您的答案如何帮助,特别是对于已经有被接受答案的问题,那么您的答案将对其他StackOverflow用户更有用。请参阅:如何撰写好的答案 - David Buck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接