Zaprojektuj Android EditText, aby wyświetlać komunikat o błędzie zgodnie z opisem Google

151

Potrzebuję pliku, EditTextktóry wygląda następująco: onError:

wprowadź opis obrazu tutaj

Zamiast tego wywołanie onError wygląda tak:

wprowadź opis obrazu tutaj

Uwaga: aplikacja działa na SDK 19 (4.4.2)

min SDK to 1

Czy istnieje metoda podobna do setError, która robi to automatycznie, czy też muszę napisać do niej kod?

Dziękuję Ci

kmn
źródło
1
Jest mało prawdopodobne, abyś był w stanie to zrobić za pomocą samego pliku EditText. Bardziej prawdopodobne jest, że będziesz potrzebować czegoś, co zawija EditTextlub w inny sposób do niego dodaje. Zobacz github.com/rengwuxian/MaterialEditText .
CommonsWare

Odpowiedzi:

330

Nie ma potrzeby korzystania z biblioteki innej firmy, ponieważ Google wprowadził TextInputLayoutjako część design-support-library.

Idąc za podstawowym przykładem:

Układ

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

Uwaga: ustawienie app:errorEnabled="true"jako atrybutu TextInputLayoutnie spowoduje zmiany rozmiaru po wyświetleniu błędu - więc w zasadzie blokuje spację.

Kod

W celu wykazania błędów poniżej EditTextwystarczy wezwanie #setErrorna TextInputLayout(nie na dziecko EditText):

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

Wynik

zdjęcie przedstawiające tekst edycji z komunikatem o błędzie

Aby ukryć błąd i zresetować odcień, po prostu zadzwoń til.setError(null).


Uwaga

Aby z niego skorzystać TextInputLayout, musisz dodać do swoich build.gradlezależności:

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

Ustawianie koloru niestandardowego

Domyślnie linia EditTextbędzie czerwona. Jeśli chcesz wyświetlić inny kolor, możesz użyć następującego kodu, gdy tylko zadzwonisz setError.

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

Aby to wyczyścić, po prostu wywołaj clearColorFilterfunkcję, na przykład:

editText.getBackground().clearColorFilter();
odwrócić
źródło
3
Tak ! Otóż ​​to ! Jak jednak sprawić, by linia była czerwona?
kmn
3
@kmn Sprawienie, że czerwona linia nie wychodzi z pudełka, więc musisz to zrobić samodzielnie. Zobacz moją edycję. Jeśli chodzi o przenoszenie Podpowiedź: to afaik nie jest możliwe.
cofnij
5
@Alessio Próbowałem tylko powiedzieć, że powinno działać, gdy rozszerzasz AppCompatActivity. Niemniej jednak: Od wersji appcompat-v23 nie jest już konieczne ustawianie colorFilter, gdy tylko wywołasz textInputLayout.setError("Error messsage")kolor EditTextpowinien zmienić się na czerwony. Aby go zresetować, wystarczy zadzwonić textInputLayout.setError(null).
cofnij
3
editText.getBackground().setColorFilter(getResources().getColor(R.color.red_500_primary), PorterDuff.Mode.SRC_ATOP);nie jest już potrzebny z najnowszą biblioteką wsparcia
Antoine Bolvy
13
Po prostu chciałem, aby pamiętać, ponieważ jest to taki mały szczegół - miałem ten problem poprzez wywołanie setError na EditText, nie TextInputLayout. Widziałem tę odpowiedź i nadal nie mogłem wymyślić, co muszę zmienić. Bardzo łatwa rzecz do przeoczenia.
h_k
8

Zadzwoń myTextInputLayout.setError()zamiast myEditText.setError().

Te kontenery i zabezpieczenia mają podwójną funkcjonalność przy ustawianiu błędów. Funkcjonalność, której potrzebujesz, to funkcja kontenera. Ale do tego możesz potrzebować minimalnej wersji 23.

Zon
źródło
7

Twój EditTextpowinien być zapakowany wTextInputLayout

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

Aby otrzymać komunikat o błędzie, taki jak chcesz, ustaw błąd na TextInputLayout

TextInputLayout tilEmail = (TextInputLayout) findViewById(R.id.tilEmail);
if (error){
    tilEmail.setError("Invalid email id");    
}

Należy dodać zależność biblioteki obsługi projektu. Dodaj tę linię do swoich zależności gradle

compile 'com.android.support:design:22.2.0'
aqel
źródło
4

Odpowiedź reVerse jest świetna, ale nie wskazała, jak usunąć pływającą etykietkę błędu

Musisz edittext.setError(null)to usunąć.
Poza tym, jak ktoś zauważył, nie potrzebujeszTextInputLayout.setErrorEnabled(true)

Układ

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

Kod

TextInputLayout til = (TextInputLayout) editText.getParent();
til.setError("Your input is not valid...");
editText.setError(null);
ericn
źródło
1
TextInputLayout til = (TextInputLayout)editText.getParent();
til.setErrorEnabled(true);
til.setError("some error..");
Max Bazaleev
źródło
7
setErrorEnabled nie jest potrzebny
JacksOnF1re
0

Jeśli ktoś nadal napotyka błąd podczas korzystania z biblioteki projektów Google, jak wspomniano w odpowiedzi, użyj tego jako komentarza @h_k, który jest -

Zamiast wywoływać setError w TextInputLayout , możesz używać setError w samym EditText .

B.shruti
źródło
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();
            } 
}
}
MEGHA DOBARIYA
źródło
Odpowiadając na stare pytanie, twoja odpowiedź byłaby znacznie bardziej przydatna dla innych użytkowników StackOverflow, gdybyś zawarł kontekst wyjaśniający, w jaki sposób twoja odpowiedź pomaga, szczególnie w przypadku pytania, które ma już zaakceptowaną odpowiedź. Zobacz: Jak napisać dobrą odpowiedź .
David Buck