Android: EditText girişini nasıl doğrulayabilirim?


169

EditTexts bir dizi form giriş doğrulaması yapmak gerekiyor. Kullanıcı her birine yazdıktan sonra doğrulama tetiklemek için OnFocusChangeListeners kullanıyorum, ancak bu son EditText için istendiği gibi davranmaz.

Son EditText'e yazarken "Bitti" düğmesine tıklarsam, InputMethod'un bağlantısı kesilir, ancak EditText'te teknik olarak odak asla kaybolmaz (ve böylece doğrulama asla gerçekleşmez).

En iyi çözüm nedir?

InputMethod'un odak değiştiğinde değil, her EditText'ten ayrıldığını izlemeli miyim? Öyleyse nasıl?


1
EditText girişini, kullanıcının yazdığı sırada gerçekten doğrulamanız gerekiyor mu? Kullanıcı Bitti düğmesini tıkladıktan sonra neden EditText'i doğrulamıyorsunuz?
Cristian

Bu tam olarak istediğim şey: Kullanıcı Bitti düğmesini tıklattığında metnin doğrulanması için (Bitti düğmesi ile QWERTY InputManager'daki "Bitti" düğmesini kastediyorum ... formun gönderme düğmesi DEĞİLDİR). Bitti düğmesine bastığımda, odak formdaki son öğeye kalır ve doğrulama yöntemim hiçbir zaman tetiklenmez. İfadem açıktır ...
Stefan

@Cristian'ın çözümü tam olarak aradığım şeydi ve burada bulundu: stackoverflow.com/questions/43013812/…
LampPost

@Cristian biraz geç geliyor, ama EditText en validate olan bir çözüm arıyorum iken kişi yazarak olduğunu. Bir Giriş / Kayıt formum var ve sadece form verileri geçerli olduğunda "Gönder" düğmesini göstermek istiyorum .
Zonker.in.Geneva

Yanıtlar:


154

Neden kullanmıyorsun TextWatcher?

Onaylanacak birkaç EditTextkutunuz olduğundan, aşağıdakilerin size uygun olacağını düşünüyorum:

  1. Etkinliğiniz android.text.TextWatcherarayüzü uygular
  2. TextChanged dinleyicilerini size EditText kutularına eklersiniz
txt1.addTextChangedListener(this);
txt2.addTextChangedListener(this);
txt3.addTextChangedListener(this);
  1. Geçersiz kılınan yöntemlerden, afterTextChanged(Editable s)yöntemi aşağıdaki gibi kullanabilirsiniz
@Override
public void afterTextChanged(Editable s) {
    // validation code goes here
}

Editable sGerçekten EditText kutunun metin değiştiriliyor hangi bulmak için yardımcı olmuyor. Ancak EditText kutularının içeriğini doğrudan

String txt1String = txt1.getText().toString();
// Validate txt1String

aynı yöntemle. Umarım netim ve eğer öyleysem yardımcı olur! :)

EDIT: Daha temiz bir yaklaşım için Christopher Perry'nin aşağıdaki cevabına bakınız.


3
Tam olarak ihtiyacım olan şeye benziyor. TextWatcher'ı (SDK / API için yeni) duymamıştım, ama test edeceğim ve düşündüğüm şekilde davranıp davranmadığını göreceğim. Bilgi için teşekkürler!
Stefan

1
rica ederim! :) şimdi doğruladığınıza göre, kullanıcıyı doğrulama hatası hakkında nasıl bilgilendireceğinizi paylaşabilir misiniz? Şu anda aynı yöntem için en iyi yöntemleri arıyorum.
Niks

Nikhil Patil, Toast'ı kullanıcıya yanlış bir şey yaptıklarını bildirmek için kullanıyorum. Bunun davanızda etkili olmamasının bir nedeni var mı?
Yevgeny Simkin

5
Tabii ki, Tost android üzerinde doğal bir yoldur. Ancak ekranda doğrulama gerektiren önemli miktarda öğe olduğunda, tostlar doğru seçim gibi görünmüyor. (IMHO, Kullanıcıyı kızdırır) TextView.setError () ( developer.android.com / reference / android / widget /…
Niks

1
TextWatcher'da zayıf destek olmasına rağmen, işe yarıyor ... tür!
Tivie

126

TextWatcher benim zevkime göre biraz ayrıntılı, bu yüzden yutmak için biraz daha kolay bir şey yaptım:

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 */ }
}

Sadece şu şekilde kullanın:

editText.addTextChangedListener(new TextValidator(editText) {
    @Override public void validate(TextView textView, String text) {
       /* Validation code here */
    }
});

4
@fremmedehenvendelser: her EditTextIS-ATextView
Niks

2
soyut sınıfın harika soyutlama ve kullanımı
Saher Ahwal

1
@fullmeriffic büyük olasılıkla EditText'inizi başlatmadıysanız. addTextChangedListenerDüzenleme metninizi görünümden çözdükten sonra aradığınızdan emin olun
Ghostli

1
@StephaneEybert Bu anonim bir sınıf
Christopher Perry

2
Uygulamada arayüz ayrımı ilkesi
Maciej Beimcik

92

Bir hata oluştuğunda hoş doğrulama açılır pencereleri ve görüntüleri istiyorsanız, burada açıkladığım gibi sınıf setErroryöntemini kullanabilirsinizEditText

Bağlantılı yazının yazarı Donn Felker'den alınan setError kullanımının ekran görüntüsü


Bir TextWatcher'ın iki EditText'e erişmesini nasıl sağlar? Başarılı bir şekilde benim TextWatcher ekledim passwordConfirmTextField, ama ben diğeri referans gerekir passwordTextField, böylece onları karşılaştırabilirsiniz. Baska öneri?
Zonker.in.Geneva

26

Doğrulama mantığının ayrıntı düzeyini azaltmak için Android için bir kitaplık yazdım . Ek Açıklamalar ve yerleşik kuralları kullanarak günlük doğrulamaların çoğunu halleder. Gibi kısıtlamalar vardır @TextRule, @NumberRule, @Required, @Regex, @Email, @IpAddress, @Password, vb

Bu ek açıklamaları kullanıcı arayüzü pencere öğesi referanslarınıza ekleyebilir ve doğrulama yapabilirsiniz. Ayrıca, uzak bir sunucudan benzersiz kullanıcı adını kontrol etmek gibi durumlar için ideal olan doğrulamaları senkronize olmayan bir şekilde gerçekleştirmenize de olanak tanır.

Proje ana sayfasında ek açıklamaların nasıl kullanılacağına ilişkin bir örnek vardır . Doğrulamalar için özel kurallar yazma konusunda örnek kodlar yazdığım ilgili blog gönderisini de okuyabilirsiniz .

Kitaplığın kullanımını gösteren basit bir örnek.

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

Kütüphane genişletilebilir, Rulesınıfı genişleterek kendi kurallarınızı yazabilirsiniz .


Bu kütüphane bir cazibe gibi çalışıyor. Ancak @TextRule ek açıklamaları sürüm 2.0.3'ten kaldırıldı mı?
LTroya

1
Bu, @Lengthek açıklama ile değiştirildi .
Ragunath Jawahar

@RagunathJawahar Gelen verileri, Ie kişisini doğrularsanız doğrulama çalışmaz, bu yüzden Niyet -> Kişiler'den gelen E-postaları doğrulamaya çalışıyorum, ancak bir kez EditText'e odaklanıp silindikten sonra doğrulama yapıyorum TextChange üzerinde doğrulama da deniyor ve Contact'tan veri aldığımızda validate () de çağrılıyor.
Ronak Mehta

11

Bu buradan güzel bir çözümdü

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}); 

boşlukla birlikte nasıl kullanabilirim ve yan yana iki boşluk bırakmayabilirim?
chiru

10

Güncellenmiş yaklaşım - TextInputLayout:

Google yakın zamanda tasarım desteği kütüphane başlattı ve denilen bir bileşeni vardır TextInputLayout ve üzerinden bir hatayı gösteren destekler setErrorEnabled(boolean)ve setError(CharSequence).

Bu nasıl kullanılır?

Adım 1: EditText'inizi TextInputLayout ile sarın:

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

2. Adım: Girişi doğrulayın

// 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);
    }
}

Github veri havuzum üzerinde bir örnek oluşturdum , isterseniz örneği inceleyin!


En iyi cevap, ama kullanmak zorundaydım com.google.android.material.textfield.TextInputLayout( maddi değişikliğe dikkat edin ). Bu yanıtı aldım: stackoverflow.com/a/56753953/900394
Alaa M.

8

Doğal olarak bazı doğrulama yöntemlerini destekleyen ve aslında çok esnek olan EditText'i genişleten bir sınıf yazdım.

Geçerli olarak, yazarken, yerel olarak xml öznitelikleri doğrulama yöntemleri ile desteklenir :

  1. alfa
  2. alfa sayısal
  3. sayısal
  4. genel ifade
  5. ip boşluğu

Buradan kontrol edebilirsiniz

Umarım tadını çıkarırsın :)


7

Android'de metin girişlerini doğrulamak için InputFilter'ı daha uygun buluyorum.

İşte basit bir örnek: Android'de bir EditText'teki karakterleri sınırlamak için InputFilter'ı nasıl kullanabilirim?

Kullanıcılara kısıtlamalarınız hakkında geri bildirimde bulunmak için bir Tost ekleyebilirsiniz. Ayrıca android: inputType etiketini kontrol edin.


1
Bu, siz yazdıkça doğrulanabilecek şeyler için güzel bir çözümdür (alfa sayısal giriş), ancak yalnızca kullanıcı giriş (e-posta adresi) girdikten sonra doğrulanması gereken şeyler için işe yaramaz.
Peter Ajtai

Tostu nasıl tetiklersin? Filtre herhangi bir metin gözlemcinin tepki vermesini engelliyor ... Belki bir onKeyListener ile?
span

Tost'u filter () yönteminden (InputFilter sınıfında) IF koşulu ile tetikledim.
Moisés

6

Değerlerimin bir durumda imzasız kayan nokta değerleri, diğerinde imzalı kayan nokta değerleri olduğunu test etmek için alanlar arası doğrulama yapmam gerekiyordu. İşte benim için işe yarayan:

    <EditText
        android:id="@+id/x" 
        android:background="@android:drawable/editbox_background" 
        android:gravity="right" 
        android:inputType="numberSigned|numberDecimal" 
    />

"NumberSigned | numberDecimal" içinde boşluk olmamalıdır. Örneğin: "numberSigned | numberDecimal" çalışmaz. Neden olduğundan emin değilim.


5

Bu gerçekten umut verici görünüyor ve doktor bana ne sipariş etti:

Metin Doğrulayıcıyı Düzenle

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

özel doğrulayıcılar ve yerleşik olanlar:

  • regexp : özel regexp için
  • numeric : yalnızca sayısal bir alan için
  • alpha : yalnızca alfa alanı için
  • alphaNumeric : tahmin et ne oldu?
  • Kişi Adı : girilen metnin kişinin adı mı yoksa soyadı mı olduğunu kontrol eder.
  • personFullName : girilen değerin tam bir tam ad olup olmadığını kontrol eder.
  • email : alanın geçerli bir e-posta olup olmadığını kontrol eder
  • creditCard : alanın Luhn Algorithm kullanan geçerli bir kredi kartı içerdiğini kontrol eder
  • phone : alanın geçerli bir telefon numarası içerip içermediğini kontrol eder
  • domainName : alanın geçerli bir alan adı içerdiğini kontrol eder (testi her zaman API Seviyesi <8'de geçirir)
  • ipAddress : alanın geçerli bir ip adresi içerip içermediğini kontrol eder
  • webUrl : alanın geçerli bir URL içerdiğini kontrol eder (testi her zaman API Seviyesi <8'de geçirir)
  • tarih : alanın geçerli bir tarih / tarih / saat biçimi olup olmadığını kontrol eder (customFormat ayarlanırsa, customFormat ile kontrol eder)
  • nocheck : Alanın boşluğu dışında hiçbir şeyi kontrol etmez.

2

Main.xml dosyasında

Düzenleme metninde yalnızca alfabe karakterinin kabul edebileceğini doğrulamak için aşağıdaki attrubute ifadesini koyabilirsiniz.

Bunu yap :

  android:entries="abcdefghijklmnopqrstuvwxyz"

2

Kullanıcı klavyede "Bitti" düğmesine bastığında dinleyerek istediğiniz davranışı elde edebilir, ayrıca "Android form doğrulama - doğru yol" yayınımda EditText ile çalışma hakkında diğer ipuçlarını da kontrol edebilirsiniz.

Basit 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;
    }});  

0

e-posta ve şifre doğrulaması için deneyin

  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();
}

-2

İçinde kolayca bir malzeme tasarımı EditText ve EditTextLayout doğrulayabilirsiniz android için bu kütüphane oluşturduk:

    compile 'com.github.TeleClinic:SmartEditText:0.1.0'

o zaman bu şekilde kullanabilirsiniz:

<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.*" />

Sonra bunun geçerli olup olmadığını kontrol edebilirsiniz:

    ageSmartEditText.check()

Daha fazla örnek ve özelleştirme için https://github.com/TeleClinic/SmartEditText deposunu kontrol edin

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.