Android: Jak mogę zweryfikować wejście EditText?
Muszę zrobić walidację wprowadzania formularzy na serii EditText. Używam OnFocusChangeListeners, aby uruchomić walidację po wpisaniu użytkownika do każdego z nich, ale to nie zachowuje się tak, jak pożądane dla ostatniego EditText.
Jeśli kliknę na przycisk "Gotowe" podczas wpisywania do ostatecznego EditText, wtedy InputMethod jest odłączony, ale technicznie fokus nigdy nie jest tracony na EditText (a więc Walidacja nigdy nie występuje).
Jakie jest najlepsze rozwiązanie?
Czy powinienem monitorować kiedy InputMethod odłącza się od każdego EditText, a nie gdy zmienia się fokus? Jeśli tak, to w jaki sposób?
14 answers
Dlaczego nie użyjesz TextWatcher
?
Ponieważ masz liczbę EditText
skrzynek do potwierdzenia, myślę, że następujące będą ci pasować:
- Twoja aktywność implementuje
android.text.TextWatcher
interfejs - dodajesz TextChanged listeners do skrzynek EditText
txt1.addTextChangedListener(this);
txt2.addTextChangedListener(this);
txt3.addTextChangedListener(this);
- z nadpisanych metod można użyć metody
afterTextChanged(Editable s)
w następujący sposób
@Override
public void afterTextChanged(Editable s) {
// validation code goes here
}
Editable s
tak naprawdę nie pomaga znaleźć, który tekst w polu EditText jest zmieniany. Ale można bezpośrednio sprawdź zawartość pól EditText jak
String txt1String = txt1.getText().toString();
// Validate txt1String
W tej samej metodzie. Mam nadzieję, że wszystko jasne, a jeśli tak, to pomoże! :)
EDIT: aby uzyskać czystsze podejście, zapoznaj się z odpowiedzią Christophera Perry ' ego poniżej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:18
Texttwatcher jest trochę gadatliwy jak na mój gust, więc zrobiłem coś łatwiejszego do przełknięcia:
public abstract class TextValidator implements TextWatcher {
private final TextView textView;
public TextValidator(TextView textView) {
this.textView = textView;
}
public abstract void validate(TextView textView, String text);
@Override
final public void afterTextChanged(Editable s) {
String text = textView.getText().toString();
validate(textView, text);
}
@Override
final public void beforeTextChanged(CharSequence s, int start, int count, int after) { /* Don't care */ }
@Override
final public void onTextChanged(CharSequence s, int start, int before, int count) { /* Don't care */ }
}
Po prostu użyj go tak:
editText.addTextChangedListener(new TextValidator(editText) {
@Override public void validate(TextView textView, String text) {
/* Validation code here */
}
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-11 20:16:29
Jeśli chcesz ładne popupy walidacji i obrazy, gdy wystąpi błąd, możesz użyć setError
metoda klasy EditText
jak opisuję TUTAJ
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-07 19:01:40
W celu zmniejszenia szczegółowości logiki walidacji napisałem bibliotekę dla Androida . Obsługuje większość codziennych walidacji za pomocą adnotacji i wbudowanych reguł. Istnieją ograniczenia, takie jak @TextRule
, @NumberRule
, @Required
, @Regex
, @Email
, @IpAddress
, @Password
, itd.,
Możesz dodać te adnotacje do odniesień do widgetów UI i przeprowadzić walidacje. Umożliwia również asynchronicznie Przeprowadzanie walidacji, co jest idealne w sytuacjach, takich jak sprawdzanie unikalna nazwa użytkownika z serwera zdalnego.
Na stronie głównej projektu znajduje się przykład użycia adnotacji. Możesz również przeczytać powiązany post na blogu , w którym napisałem przykładowe kody, jak pisać niestandardowe zasady walidacji.
Oto prosty przykład przedstawiający sposób korzystania z biblioteki.
@Required(order = 1)
@Email(order = 2)
private EditText emailEditText;
@Password(order = 3)
@TextRule(order = 4, minLength = 6, message = "Enter at least 6 characters.")
private EditText passwordEditText;
@ConfirmPassword(order = 5)
private EditText confirmPasswordEditText;
@Checked(order = 6, message = "You must agree to the terms.")
private CheckBox iAgreeCheckBox;
Biblioteka jest rozszerzalna, możesz napisać własne reguły rozszerzając klasę Rule
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-23 14:06:07
To było ładne rozwiązanie z Tutaj
InputFilter filter= new InputFilter() {
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
for (int i = start; i < end; i++) {
String checkMe = String.valueOf(source.charAt(i));
Pattern pattern = Pattern.compile("[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz123456789_]*");
Matcher matcher = pattern.matcher(checkMe);
boolean valid = matcher.matches();
if(!valid){
Log.d("", "invalid");
return "";
}
}
return null;
}
};
edit.setFilters(new InputFilter[]{filter});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:18
Zaktualizowane podejście-TextInputLayout:
Google niedawno uruchomiło bibliotekę design support library i istnieje jeden komponent o nazwie TextInputLayout i obsługuje wyświetlanie błędu przez setErrorEnabled(boolean)
i setError(CharSequence)
.
Jak go używać?
Krok 1: owiń swój EditText za pomocą TextInputLayout:
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/layoutUserName">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="hint"
android:id="@+id/editText1" />
</android.support.design.widget.TextInputLayout>
Krok 2: zweryfikuj dane wejściowe
// validating input on a button click
public void btnValidateInputClick(View view) {
final TextInputLayout layoutUserName = (TextInputLayout) findViewById(R.id.layoutUserName);
String strUsername = layoutLastName.getEditText().getText().toString();
if(!TextUtils.isEmpty(strLastName)) {
Snackbar.make(view, strUsername, Snackbar.LENGTH_SHORT).show();
layoutUserName.setErrorEnabled(false);
} else {
layoutUserName.setError("Input required");
layoutUserName.setErrorEnabled(true);
}
}
Stworzyłem przykład w moim repozytorium Github, sprawdź przykład, jeśli chcesz!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-25 10:16:24
Uważam, że InputFilter jest bardziej odpowiedni do walidacji wejść tekstowych na Androida.
Oto prosty przykład: Jak używać InputFilter do ograniczania znaków w edytowanym tekście w Androidzie?
Możesz dodać Toast za opinię użytkownika o swoich ograniczeniach. Sprawdź również tag android: inputType.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:17
Napisałem klasę, która rozszerza EditText, która natywnie obsługuje niektóre metody walidacji i jest bardzo elastyczna.
Aktualne, jak piszę, natywnie obsługiwane przez atrybuty xml metody walidacji to:
- Alfa
- alpha numeric
- numeryczne
- generic regexp
- pustość strun
Możesz to sprawdzić tutaj
Mam nadzieję, że ci się spodoba:)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-30 14:49:34
Musiałem przeprowadzić walidację wewnątrz pola, a nie między polami, aby sprawdzić, czy moje wartości były niepodpisanymi wartościami zmiennoprzecinkowymi w jednym przypadku, a podpisanymi wartościami zmiennoprzecinkowymi w innym. Oto, co wydaje mi się działać:
<EditText
android:id="@+id/x"
android:background="@android:drawable/editbox_background"
android:gravity="right"
android:inputType="numberSigned|numberDecimal"
/>
Uwaga, nie możesz mieć spacji w "numberSigned|numberDecimal". Na przykład: "numberSigned | numberDecimal" nie będzie działać. Nie wiem dlaczego.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-01 23:50:09
To wygląda naprawdę obiecująco i dokładnie to, co lekarz zamówił dla mnie:
public void onClickNext(View v) {
FormEditText[] allFields = { etFirstname, etLastname, etAddress, etZipcode, etCity };
boolean allValid = true;
for (FormEditText field: allFields) {
allValid = field.testValidity() && allValid;
}
if (allValid) {
// YAY
} else {
// EditText are going to appear with an exclamation mark and an explicative message.
}
}
Walidatory niestandardowe plus te wbudowane:
- regexp : dla niestandardowych regexp
- numeric : tylko dla pola numerycznego
- alpha : dla pola tylko Alfa
- / Align = "left" /
- personName : sprawdza, czy wprowadzony tekst jest osobą pierwszą lub ostatnią nazwisko.
- personFullName : sprawdza, czy wprowadzona wartość jest pełną pełną nazwą.
- email : sprawdza, czy pole jest prawidłowym adresem e-mail
- creditCard : sprawdza, czy pole zawiera ważną kartę kredytową za pomocą algorytmu Luhna
- phone : sprawdza, czy pole zawiera prawidłowy numer telefonu
- domainName : sprawdza, czy pole zawiera poprawną nazwę domeny (zawsze przechodzi test na poziomie API
- ipAddress: sprawdza, czy pole zawiera poprawny adres ip
- webUrl : sprawdza, czy pole zawiera poprawny adres url (zawsze przechodzi test na poziomie API
- date : sprawdza, czy pole jest poprawnym formatem daty / datetime (jeśli ustawiony jest customFormat, sprawdza za pomocą customFormat)
- nocheck : nie sprawdza niczego poza pustością pola.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-10 12:31:26
In main.plik xml
Możesz umieścić następujący attrubute, aby potwierdzić, że tylko znak alfabetyczny może być zaakceptowany w edittext.
Zrób to:
android:entries="abcdefghijklmnopqrstuvwxyz"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-07 06:02:58
Możesz uzyskać pożądane zachowanie, słuchając, gdy użytkownik naciśnie przycisk "Gotowe" na klawiaturze, a także sprawdź inne wskazówki dotyczące pracy z EditText w moim poście "Walidacja formularza Android-właściwy sposób"
Przykładowy kod:
mTextView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView view, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
validateAndSubmit();
return true;
}
return false;
}});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-11 11:55:23
Do weryfikacji adresu e-mail i hasła spróbuj
if (isValidEmail(et_regemail.getText().toString())&&etpass1.getText().toString().length()>7){
if (validatePassword(etpass1.getText().toString())) {
Toast.makeText(getApplicationContext(),"Go Ahead".....
}
else{
Toast.makeText(getApplicationContext(),"InvalidPassword".....
}
}else{
Toast.makeText(getApplicationContext(),"Invalid Email".....
}
public boolean validatePassword(final String password){
Pattern pattern;
Matcher matcher;
final String PASSWORD_PATTERN = "^(?=.*[0-9])(?=.*[A-Z])(?=.*
[@#$%^&+=!])(?=\\S+$).{4,}$";
pattern = Pattern.compile(PASSWORD_PATTERN);
matcher = pattern.matcher(password);
return matcher.matches();
}
public final static boolean isValidEmail(CharSequence target) {
if (target == null)
return false;
return android.util.Patterns.EMAIL_ADDRESS.matcher(target).matches();
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-10 07:04:58
Stworzyłem tę bibliotekę dla Androida, w której możesz łatwo zweryfikować projekt materiału EditText inside I EditTextLayout w następujący sposób:
compile 'com.github.TeleClinic:SmartEditText:0.1.0'
Wtedy możesz użyć go tak:
<com.teleclinic.kabdo.smartmaterialedittext.CustomViews.SmartEditText
android:id="@+id/passwordSmartEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:setLabel="Password"
app:setMandatoryErrorMsg="Mandatory field"
app:setPasswordField="true"
app:setRegexErrorMsg="Weak password"
app:setRegexType="MEDIUM_PASSWORD_VALIDATION" />
<com.teleclinic.kabdo.smartmaterialedittext.CustomViews.SmartEditText
android:id="@+id/ageSmartEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:setLabel="Age"
app:setMandatoryErrorMsg="Mandatory field"
app:setRegexErrorMsg="Is that really your age :D?"
app:setRegexString=".*\\d.*" />
Następnie możesz sprawdzić, czy jest to ważne w następujący sposób:
ageSmartEditText.check()
Aby uzyskać więcej przykładów i dostosować sprawdź repozytorium https://github.com/TeleClinic/SmartEditText
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-22 09:09:59