Дизайн Android EditText, чтобы показать сообщение об ошибке, как описано Google

151

Мне нужно EditText, чтобы это выглядело так:

введите описание изображения здесь

вызов onError выглядит следующим образом:

введите описание изображения здесь

Примечание: приложение работает на SDK 19 (4.4.2)

мин SDK равен 1

Есть ли метод, похожий на setError, который делает это автоматически, или я должен написать код для него?

Спасибо

к.м.н.
источник
1
Вы вряд ли сможете сделать это только с помощью EditText. Скорее всего, вам нужно что-то, что оборачивает EditTextили иным образом добавляет к этому. См. Github.com/rengwuxian/MaterialEditText .
CommonsWare

Ответы:

330

Нет необходимости использовать стороннюю библиотеку, так как Google представил TextInputLayoutкак часть design-support-library.

Следуя базовому примеру:

раскладка

<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вам просто нужно позвонить #setErrorна TextInputLayout(НЕ на ребенка 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
Да ! Это оно ! Как вы делаете линию красной, хотя?
км
3
@kmn Выделение линии красным не выходит из коробки, поэтому вам нужно сделать это самостоятельно. Смотрите мое редактирование. С точки зрения перемещения Подсказка: это не возможно.
Пересмотрите
5
@Alessio Я просто пытался сказать, что это должно работать, когда вы расширяете AppCompatActivity. Тем не менее: Начиная с appcompat-v23 больше не нужно устанавливать colorFilter, как только вы вызываете, textInputLayout.setError("Error messsage")цвет EditTextдолжен стать красным. Для того чтобы его сбросить, достаточно позвонить textInputLayout.setError(null).
Вернуть
3
editText.getBackground().setColorFilter(getResources().getColor(R.color.red_500_primary), PorterDuff.Mode.SRC_ATOP);больше не нужна больше с последней библиотекой поддержки
Антуан Болви
13
Просто хотел заметить, поскольку это такая маленькая деталь - у меня возникла эта проблема, вызвав setError для EditText, а не для TextInputLayout. Я видел этот ответ и все еще не мог понять, что мне нужно изменить. Очень легко пропустить.
h_k
8

Позвони 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'
Aqel
источник
4

Ответ 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);
ericn
источник
1
TextInputLayout til = (TextInputLayout)editText.getParent();
til.setErrorEnabled(true);
til.setError("some error..");
Макс Базалеев
источник
7
setErrorEnabled не требуется
JacksOnF1re
0

Если кто-то все еще сталкивается с ошибкой при использовании библиотеки дизайна Google, как упомянуто в ответе, пожалуйста, используйте это как комментарий @h_k, который является -

Вместо вызова setError для TextInputLayout , вы можете использовать setError для самого EditText .

B.shruti
источник
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, если бы вы включили некоторый контекст для объяснения того, как ваш ответ помогает, особенно для вопроса, на который уже есть принятый ответ. Смотрите: Как мне написать хороший ответ .
Дэвид Бак