Android: Làm cách nào tôi có thể xác thực đầu vào EditText?


169

Tôi cần thực hiện xác thực nhập mẫu trên một loạt EditTexts. Tôi đang sử dụng OnF FocusChangeListener để kích hoạt xác thực sau khi người dùng nhập từng loại, nhưng điều này không hoạt động như mong muốn cho EditText cuối cùng.

Nếu tôi nhấp vào nút "Xong" trong khi nhập vào EditText cuối cùng thì InputMethod sẽ bị ngắt kết nối, nhưng không thể mất tiêu điểm về mặt kỹ thuật đối với EditText (và vì vậy việc xác thực không bao giờ xảy ra).

Giải pháp tốt nhất là gì?

Tôi có nên theo dõi khi InputMethod hủy liên kết từ mỗi EditText thay vì khi tiêu điểm thay đổi không? Nếu vậy thì thế nào?


1
Bạn có thực sự cần xác thực đầu vào EditText cùng lúc người dùng đang gõ không? Tại sao bạn không xác thực các EditText sau khi người dùng nhấp vào nút Xong?
Cristian

Đó chính xác là những gì tôi muốn: để văn bản được xác minh khi người dùng nhấp vào nút Xong (bằng nút Xong tôi có nghĩa là nút "Xong" trên Trình quản lý đầu vào QWERTY ... KHÔNG phải nút gửi biểu mẫu). Ngoại trừ khi tôi nhấn nút Xong, tiêu điểm sẽ nằm ở phần tử cuối cùng trong biểu mẫu và phương thức xác thực của tôi không bao giờ được kích hoạt. Hy vọng từ ngữ của tôi là rõ ràng ...
Stefan

Giải pháp của @Cristian chính xác là những gì tôi đang tìm kiếm và được tìm thấy ở đây: stackoverflow.com/questions/43013812/ chủ
LampPost

@Cristian Đến hơi muộn, nhưng tôi đang tìm một giải pháp trong đó các EditText là hợp lệ trong khi người đó đang gõ. Tôi có một hình thức đăng nhập / Đăng ký và tôi muốn hiển thị nút "Gửi" chỉ khi dữ liệu mẫu là hợp lệ.
Zonker.in.Geneva

Câu trả lời:


154

Tại sao bạn không sử dụng TextWatcher?

Vì bạn có một số EditTexthộp được xác nhận, tôi nghĩ những điều sau đây sẽ phù hợp với bạn:

  1. Hoạt động của bạn thực hiện android.text.TextWatchergiao diện
  2. Bạn thêm trình nghe TextChanged vào hộp EditText
txt1.addTextChangedListener(this);
txt2.addTextChangedListener(this);
txt3.addTextChangedListener(this);
  1. Trong số các phương thức được ghi đè, bạn có thể sử dụng afterTextChanged(Editable s)phương thức như sau
@Override
public void afterTextChanged(Editable s) {
    // validation code goes here
}

Các Editable skhông thực sự giúp đỡ để tìm mà văn bản EditText hộp đang được thay đổi. Nhưng bạn có thể trực tiếp kiểm tra nội dung của các hộp EditText như

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

trong cùng một phương pháp. Tôi hy vọng tôi rõ ràng và nếu tôi, nó sẽ giúp! :)

EDIT: Để biết cách tiếp cận sạch hơn, hãy tham khảo câu trả lời của Christopher Perry bên dưới.


3
Trông giống như chính xác những gì tôi cần. Chưa từng nghe về TextWatcher (mới đối với SDK / API), nhưng tôi sẽ kiểm tra nó và xem liệu nó có hoạt động theo cách tôi nghĩ không. Cảm ơn bạn về thông tin!
Stefan

1
không có gì! :) bây giờ khi bạn xác nhận nó, bạn có thể chia sẻ làm thế nào bạn sẽ thông báo cho người dùng về sự thất bại xác nhận? Tôi hiện đang tìm kiếm các phương pháp tốt nhất cho cùng.
Niks

Nikhil Patil, tôi chỉ sử dụng Toast để cho người dùng biết họ đã làm gì đó sai. Có một số lý do tại sao điều đó sẽ không có hiệu quả trong trường hợp của bạn?
Yevgeny Simkin

5
Tất nhiên, Toast là một cách tự nhiên trên Android. Nhưng khi chúng ta có một số lượng đáng kể các yếu tố trên màn hình cần xác thực, thì bánh mì dường như không phải là lựa chọn chính xác. (IMHO, Nó sẽ gây khó chịu cho người dùng) Tôi đã thử nghiệm với TextView.setError () ( developer.android.com / tham khảo / android / widget /
SSH

1
Mặc dù có sự hỗ trợ kém trên TextWatcher, nhưng nó hoạt động ... tốt!
Tivie

125

TextWatcher hơi dài dòng theo sở thích của tôi, vì vậy tôi đã làm cho thứ gì đó dễ nuốt hơn một chút:

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

Chỉ cần sử dụng nó như thế này:

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

4
@fremmedehenvendelser: mỗi EditTextIS-ATextView
Niks

2
sự trừu tượng tuyệt vời và việc sử dụng lớp trừu tượng
Saher Ahwal

1
@fullmeriffic rất có thể bạn đã không khởi tạo EditText của mình. Hãy chắc chắn rằng bạn đang gọi addTextChangedListenersau khi giải quyết edittext của bạn từ chế độ xem
Ghostli

1
@StephaneEybert Đó là một lớp ẩn danh
Christopher Perry

2
Nguyên tắc phân tách giao diện trong thực tế
Maciej Beimcik

92

Nếu bạn muốn quảng cáo và hình ảnh xác thực đẹp khi xảy ra lỗi, bạn có thể sử dụng setErrorphương thức của EditTextlớp như tôi mô tả ở đây

Ảnh chụp màn hình về việc sử dụng setError được lấy từ Donn Felker, tác giả của bài đăng được liên kết


Làm cách nào để bạn có được TextWatcher để truy cập hai EditTexts? Tôi đã thêm thành công TextWatcher cho tôi passwordConfirmTextField, nhưng tôi cần tham khảo cái khác passwordTextField, để tôi có thể so sánh chúng. Bất kỳ đề xuất?
Zonker.in.Geneva

26

Để giảm mức độ chi tiết của logic xác thực, tôi đã tạo một thư viện cho Android . Nó chăm sóc hầu hết các xác nhận hàng ngày bằng cách sử dụng Chú thích và quy tắc tích hợp. Có những hạn chế như @TextRule, @NumberRule, @Required, @Regex, @Email, @IpAddress, @Password, vv

Bạn có thể thêm các chú thích này vào các tham chiếu tiện ích UI và thực hiện xác nhận. Nó cũng cho phép bạn thực hiện xác nhận không đồng bộ, lý tưởng cho các tình huống như kiểm tra tên người dùng duy nhất từ ​​máy chủ từ xa.

Có một ví dụ trên trang chủ của dự án về cách sử dụng các chú thích. Bạn cũng có thể đọc bài đăng trên blog được liên kết nơi tôi đã viết mã mẫu về cách viết quy tắc tùy chỉnh để xác thực.

Dưới đây là một ví dụ đơn giản mô tả việc sử dụng thư viện.

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

Thư viện có thể mở rộng, bạn có thể viết các quy tắc của riêng mình bằng cách mở rộng Rulelớp.


Thư viện này hoạt động như một lá bùa. Nhưng các chú thích @TextRule đã bị xóa khỏi phiên bản 2.0.3?
LTroya

1
Nó đã được thay thế bằng @Lengthchú thích.
Ragunath Jawahar

@RagunathJawahar Tôi đã lưu ý rằng xác thực không hoạt động nếu Bạn xác thực dữ liệu đến, liên hệ, vì vậy tôi đang cố xác thực Email đến từ Intent -> Danh bạ, nhưng một khi tôi tập trung vào EditText và thêm / xóa bất kỳ văn bản nào sau đó xác thực hoạt động như xác thực cũng đang được gọi trên TextChange và xác thực () cũng được gọi khi chúng tôi nhận được dữ liệu từ Liên hệ.
Ronak Mehta

11

Đây là giải pháp tốt đẹp từ đây

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

Làm thế nào để tôi sử dụng nó cùng với không gian và giới hạn không có hai không gian cạnh nhau?
chiru

10

Cách tiếp cận được cập nhật - TextInputLayout:

Google gần đây đã ra mắt thư viện hỗ trợ thiết kế và có một thành phần được gọi là TextInputLayout và nó hỗ trợ hiển thị lỗi thông qua setErrorEnabled(boolean)setError(CharSequence).

Làm thế nào để sử dụng nó?

Bước 1: Gói EditText của bạn với 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>

Bước 2: Xác thực đầu vào

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

Tôi đã tạo một ví dụ trên kho Github của mình , hãy kiểm tra ví dụ nếu bạn muốn!


Câu trả lời tốt nhất, nhưng tôi đã phải sử dụng com.google.android.material.textfield.TextInputLayout(chú ý sự thay đổi vật liệu ). Có được từ câu trả lời này: stackoverflow.com/a/56753953/900394
Alaa M.

8

Tôi đã viết một lớp mở rộng EditText hỗ trợ một số phương thức xác thực và thực sự rất linh hoạt.

Hiện nay, như tôi đã viết, natively hỗ trợ thông qua xml thuộc tính phương pháp xác nhận là:

  1. alpha
  2. số alpha
  3. số
  4. regrec chung
  5. chuỗi trống

Bạn có thể kiểm tra nó ở đây

Hy vọng la bạn se thich no :)


7

Tôi thấy InputFilter phù hợp hơn để xác thực nhập văn bản trên Android.

Đây là một ví dụ đơn giản: Làm cách nào để sử dụng InputFilter để giới hạn các ký tự trong EditText trong Android?

Bạn có thể thêm Toast để phản hồi cho người dùng về các hạn chế của bạn. Ngoài ra kiểm tra thẻ android: inputType.


1
Đây là một giải pháp tốt cho những thứ có thể xác thực khi bạn nhập (đầu vào số alpha), nhưng nó sẽ không hoạt động đối với những thứ chỉ nên xác thực khi người dùng nhập xong (địa chỉ email).
Peter Ajtai

Làm thế nào bạn sẽ kích hoạt Toast đó? Bộ lọc ngăn bất kỳ trình xem văn bản nào phản ứng ... Có lẽ với onKeyListener?
kéo dài

Tôi đã kích hoạt Toast với điều kiện IF từ phương thức filter () (trong lớp InputFilter).
Moisés

6

Tôi cần thực hiện xác thực nội bộ và không xác thực liên trường để kiểm tra xem các giá trị của tôi có phải là giá trị dấu phẩy động không dấu trong một trường hợp và đã ký các giá trị dấu phẩy động trong trường hợp khác. Đây là những gì có vẻ làm việc cho tôi:

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

Lưu ý, bạn không được có bất kỳ khoảng trắng nào bên trong "numberSign | numberDecimal". Ví dụ: "numberSign | numberDecimal" sẽ không hoạt động. Tôi cung không chăc tại sao.


5

Điều này có vẻ rất hứa hẹn và đúng như những gì tài liệu đã ra lệnh cho tôi:

Trình xác thực chỉnh sửa

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

trình xác nhận tùy chỉnh cộng với những điều này được xây dựng trong:

  • regapi : cho regrec tùy chỉnh
  • số : cho một trường số duy nhất
  • alpha : cho trường chỉ alpha
  • alphaNumeric : đoán xem?
  • personName : kiểm tra xem văn bản đã nhập là họ hay tên.
  • personFullName : kiểm tra xem giá trị đã nhập có phải là tên đầy đủ hay không.
  • email : kiểm tra xem trường đó có phải là email hợp lệ không
  • CREDITCARD : kiểm tra mà trường có chứa một thẻ tín dụng hợp lệ sử dụng Luhn Algorithm
  • phone : kiểm tra xem trường có chứa số điện thoại hợp lệ không
  • domainName : kiểm tra trường đó có chứa một tên miền hợp lệ (luôn vượt qua bài kiểm tra ở Cấp API <8)
  • ipAddress : kiểm tra xem trường có chứa địa chỉ IP hợp lệ không
  • webUrl : kiểm tra xem trường có chứa url hợp lệ không (luôn vượt qua bài kiểm tra ở Cấp API <8)
  • ngày : kiểm tra xem trường có phải là định dạng ngày / thời gian hợp lệ không (nếu customFormat được đặt, kiểm tra với customFormat)
  • nocheck : Nó không kiểm tra bất cứ thứ gì ngoại trừ khoảng trống của trường.

2

Trong tệp main.xml

Bạn có thể đặt attrubute sau để xác thực chỉ ký tự chữ cái có thể chấp nhận trong edittext.

Làm cái này :

  android:entries="abcdefghijklmnopqrstuvwxyz"

2

Bạn có thể có hành vi mong muốn bằng cách lắng nghe khi người dùng nhấn nút "Xong" trên bàn phím, đồng thời kiểm tra các mẹo khác về cách làm việc với EditText trong bài đăng của tôi "Xác thực mẫu Android - đúng cách"

Mã mẫu:

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

để xác thực email và mật khẩu

  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

Tôi đã tạo thư viện này cho Android nơi bạn có thể xác thực thiết kế vật liệu EditText bên trong và EditTextLayout dễ dàng như thế này:

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

sau đó bạn có thể sử dụng nó như thế này:

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

Sau đó, bạn có thể kiểm tra nếu nó hợp lệ như thế này:

    ageSmartEditText.check()

Để biết thêm ví dụ và tùy chỉnh, hãy kiểm tra kho lưu trữ https://github.com/TeleClinic/SmartEditText

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.