Android: ฉันจะตรวจสอบการป้อนข้อความ EditText ได้อย่างไร?


169

ฉันต้องทำการตรวจสอบความถูกต้องของอินพุตแบบฟอร์มบน EditTexts ฉันใช้ OnFocusChangeListeners เพื่อทริกเกอร์การตรวจสอบหลังจากที่ผู้ใช้พิมพ์ลงในแต่ละรายการ แต่สิ่งนี้ไม่ทำงานตามที่ต้องการสำหรับ EditText ล่าสุด

หากฉันคลิกที่ปุ่ม "เสร็จสิ้น" ในขณะที่พิมพ์ลงใน EditText สุดท้ายดังนั้น InputMethod ก็จะถูกตัดการเชื่อมต่อ แต่ในทางเทคนิคแล้วโฟกัสจะไม่หายไปที่ EditText (ดังนั้นการตรวจสอบจึงไม่เกิดขึ้น)

ทางออกที่ดีที่สุดคืออะไร

ฉันควรตรวจสอบเมื่อ InputMethod unbinds จากแต่ละ EditText แทนที่จะเปลี่ยนโฟกัสหรือไม่ ถ้าเป็นเช่นนั้นได้อย่างไร


1
คุณต้องการตรวจสอบความถูกต้องของอินพุต EditText ในเวลาเดียวกันกับที่ผู้ใช้พิมพ์หรือไม่? ทำไมคุณไม่ตรวจสอบความถูกต้องของ EditText เมื่อผู้ใช้คลิกที่ปุ่ม Done
Cristian

นั่นคือสิ่งที่ฉันต้องการ: เพื่อให้ข้อความได้รับการตรวจสอบเมื่อผู้ใช้คลิกปุ่มเสร็จ (โดยปุ่มเสร็จฉันหมายถึงปุ่ม "เสร็จสิ้น" บน QWERTY InputManager ... ไม่ใช่ปุ่มส่งของแบบฟอร์ม) ยกเว้นว่าเมื่อฉันกดปุ่ม Done โฟกัสจะอยู่ที่องค์ประกอบสุดท้ายในแบบฟอร์มและวิธีการตรวจสอบความถูกต้องของฉันจะไม่ถูกเรียก หวังว่าคำพูดของฉันเป็นที่ชัดเจน ...
สเตฟาน

วิธีการแก้ปัญหาของ @Cristian เป็นสิ่งที่ฉันกำลังมองหาและอยู่ที่นี่: stackoverflow.com/questions/43013812/…
LampPost

@Cristian มาช้า แต่ฉันกำลังมองหาโซลูชันที่ EditText นั้นตรวจสอบได้ในขณะที่บุคคลนั้นกำลังพิมพ์อยู่ ฉันมีฟอร์มเข้าสู่ระบบ / ลงทะเบียนและฉันต้องการแสดงปุ่ม "ส่ง" เฉพาะเมื่อข้อมูลในฟอร์มนั้นถูกต้อง
Zonker.in.Geneva

คำตอบ:


154

ทำไมคุณไม่ใช้TextWatcher?

เนื่องจากคุณมีจำนวนEditTextกล่องที่จะตรวจสอบฉันคิดว่าสิ่งต่อไปนี้จะเหมาะกับคุณ:

  1. กิจกรรมของคุณใช้android.text.TextWatcherอินเทอร์เฟซ
  2. คุณเพิ่ม TextChanged Listeners ให้คุณในกล่อง EditText
txt1.addTextChangedListener(this);
txt2.addTextChangedListener(this);
txt3.addTextChangedListener(this);
  1. ในวิธีการแทนที่คุณสามารถใช้afterTextChanged(Editable s)วิธีดังต่อไปนี้
@Override
public void afterTextChanged(Editable s) {
    // validation code goes here
}

Editable sไม่ได้จริงๆช่วยเพื่อหาที่ EditText กล่องข้อความจะถูกเปลี่ยน แต่คุณสามารถตรวจสอบเนื้อหาของกล่อง EditText ได้โดยตรง

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

ในวิธีเดียวกัน ฉันหวังว่าฉันชัดเจนและถ้าฉันมันช่วยได้! :)

แก้ไข:สำหรับแนวทางที่สะอาดกว่าอ้างถึงคำตอบของ Christopher Perryด้านล่าง


3
นั่นดูเหมือนสิ่งที่ฉันต้องการ ไม่เคยได้ยิน TextWatcher (ใหม่กับ SDK / API) แต่ฉันจะทดสอบและดูว่ามันทำงานตามที่ฉันคิดหรือไม่ ขอบคุณสำหรับข้อมูล!
สเตฟาน

1
ยินดีต้อนรับคุณ! :) ตอนนี้คุณกำลังตรวจสอบความถูกต้องคุณสามารถแบ่งปันวิธีที่คุณจะแจ้งผู้ใช้ถึงความล้มเหลวในการตรวจสอบความถูกต้องได้อย่างไร ฉันกำลังมองหาวิธีการที่ดีที่สุดสำหรับสิ่งเดียวกัน
Niks

Nikhil Patil ฉันแค่ใช้ Toast เพื่อให้ผู้ใช้รู้ว่าพวกเขาทำอะไรผิด มีเหตุผลบางอย่างที่จะไม่เกิดผลในกรณีของคุณหรือไม่?
Yevgeny Simkin

5
แน่นอนว่าขนมปังปิ้งเป็นวิธีที่เป็นธรรมชาติสำหรับ Android แต่เมื่อเรามีองค์ประกอบจำนวนมากบนหน้าจอที่ต้องการการตรวจสอบดูเหมือนว่าขนมปังปิ้งจะเป็นตัวเลือกที่ถูกต้อง (IMHO มันจะรบกวนผู้ใช้) ฉันได้ทดลองใช้ TextView.setError () ( developer.android.com / reference / android / widget / …
Niks

1
แม้ว่าจะมีการรองรับ TextWatcher ที่ไม่ดี แต่ก็ใช้งานได้ ...
Tivie

125

TextWatcher ค่อนข้างละเอียดสำหรับรสนิยมของฉันดังนั้นฉันจึงทำให้บางสิ่งบางอย่างง่ายขึ้นที่จะกลืน:

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

เพียงใช้มันเช่นนี้

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

4
@fremmedehenvendelser: ทุกEditTextIS-ATextView
Niks

2
สิ่งที่เป็นนามธรรมที่น่ากลัวและการใช้คลาสนามธรรม
Saher Ahwal

1
@fullmeriffic ส่วนใหญ่คุณอาจไม่ได้เริ่มต้น EditText ของคุณ ตรวจสอบให้แน่ใจว่าคุณโทรมาaddTextChangedListenerหลังจากที่แก้ไข edittext ของคุณจากมุมมอง
Ghostli


2
หลักการแยกส่วนต่อ
ประสาน

92

หากคุณต้องการป๊อปอัปการตรวจสอบที่ดีและภาพเมื่อเกิดข้อผิดพลาดคุณสามารถใช้setErrorวิธีการEditTextเรียนที่ฉันอธิบายที่นี่

สกรีนช็อตของการใช้ setError ที่นำมาจาก Donn Felker ผู้เขียนโพสต์ที่ลิงก์


คุณจะรับ TextWatcher เพื่อเข้าถึงEditTexts สองรายการได้อย่างไร ฉันเพิ่ม TextWatcher สำเร็จpasswordConfirmTextFieldแล้ว แต่ฉันต้องการอ้างอิงอีกpasswordTextFieldอันเพื่อให้สามารถเปรียบเทียบได้ ข้อเสนอแนะใด ๆ
Zonker.in.Geneva

26

เพื่อที่จะลดฟุ่มเฟื่อยของตรรกะการตรวจสอบที่ฉันได้ประพันธ์ห้องสมุดสำหรับ Android มันจะดูแลการตรวจสอบส่วนใหญ่ของวันต่อวันโดยใช้คำอธิบายประกอบและกฎในตัว มีข้อ จำกัด เช่น@TextRule, @NumberRule, @Required, @Regex, @Email, @IpAddress, @Passwordฯลฯ

คุณสามารถเพิ่มคำอธิบายประกอบเหล่านี้ไปยังการอ้างอิงวิดเจ็ต UI ของคุณและทำการตรวจสอบความถูกต้อง นอกจากนี้ยังช่วยให้คุณสามารถตรวจสอบความถูกต้องแบบอะซิงโครนัสซึ่งเหมาะสำหรับสถานการณ์เช่นการตรวจสอบชื่อผู้ใช้ที่ไม่ซ้ำจากเซิร์ฟเวอร์ระยะไกล

มีตัวอย่างอยู่ในโฮมเพจของโครงการเกี่ยวกับวิธีใช้คำอธิบายประกอบ คุณยังสามารถอ่านบล็อกโพสต์ที่เกี่ยวข้องซึ่งฉันได้เขียนโค้ดตัวอย่างเกี่ยวกับวิธีเขียนกฎที่กำหนดเองสำหรับการตรวจสอบ

นี่คือตัวอย่างง่ายๆที่แสดงให้เห็นถึงการใช้งานของห้องสมุด

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

ห้องสมุดสามารถขยายได้คุณสามารถเขียนกฎของคุณเองโดยขยายRuleชั้นเรียน


ห้องสมุดนี้ใช้งานได้อย่างมีเสน่ห์ แต่คำอธิบายประกอบ @TextRule ถูกลบออกจากเวอร์ชัน 2.0.3 แล้วหรือยัง
LTroya

1
มันถูกแทนที่ด้วย@Lengthคำอธิบายประกอบ
Ragunath Jawahar

@RagunathJawahar ฉันได้ตั้งข้อสังเกตว่าการตรวจสอบใช้งานไม่ได้หากคุณตรวจสอบข้อมูลขาเข้า, ที่อยู่ติดต่อของ Ie, ดังนั้นฉันจึงพยายามตรวจสอบอีเมลซึ่งมาจากเจตนา -> ผู้ติดต่อ แต่เมื่อฉันมุ่งเน้น EditText และเพิ่ม / ลบข้อความใด ๆ ทำงานเหมือนการตรวจสอบความถูกต้องก็ถูกเรียกบน TextChange และ validate () ก็จะถูกเรียกเมื่อเราได้รับข้อมูลจากการติดต่อ
Ronak Mehta

11

นี่เป็นทางออกที่ดีจากที่นี่

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

ฉันจะใช้มันพร้อมกับพื้นที่และ จำกัด ไม่ให้มีสองช่องว่างติดกันได้อย่างไร
chiru

10

อัพเดตวิธี - TextInputLayout:

Google ได้เปิดตัวเมื่อเร็ว ๆ นี้ห้องสมุดการสนับสนุนการออกแบบและมีเป็นองค์ประกอบหนึ่งที่เรียกว่าTextInputLayoutและสนับสนุนการแสดงข้อผิดพลาดทางและsetErrorEnabled(boolean)setError(CharSequence)

วิธีใช้งาน

ขั้นตอนที่ 1: ตัด EditText ของคุณด้วย 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>

ขั้นตอนที่ 2: ตรวจสอบความถูกต้องของอินพุต

// 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ของฉันแล้วเช็คเอาต์ตัวอย่างถ้าคุณต้องการ!


คำตอบที่ดีที่สุด แต่ฉันต้องใช้com.google.android.material.textfield.TextInputLayout(สังเกตเห็นการเปลี่ยนแปลงวัสดุ ) รับจากคำตอบนี้: stackoverflow.com/a/56753953/900394
Alaa M.

8

ฉันเขียนคลาสที่ขยาย EditText ซึ่งรองรับวิธีการตรวจสอบความถูกต้องบางวิธีและมีความยืดหยุ่นมาก

ปัจจุบันที่ผมเขียน โดยกำเนิดการสนับสนุนผ่านแอตทริบิวต์ XMLวิธีการตรวจสอบคือ:

  1. แอลฟา
  2. ตัวเลขและตัวอักษร
  3. เป็นตัวเลข
  4. regexp ทั่วไป
  5. ความว่างเปล่าของสตริง

คุณสามารถตรวจสอบได้ที่นี่

หวังว่าคุณจะสนุกกับมัน :)


7

ฉันพบว่า InputFilter เหมาะสมกว่าในการตรวจสอบอินพุตข้อความใน Android

นี่คือตัวอย่างง่ายๆ: ฉันจะใช้ InputFilter เพื่อ จำกัด อักขระใน EditText ใน Android ได้อย่างไร

คุณสามารถเพิ่ม Toast เพื่อติชมผู้ใช้เกี่ยวกับข้อ จำกัด ของคุณ ตรวจสอบ android: แท็ก inputType ด้วย


1
นี่เป็นวิธีแก้ปัญหาที่ดีสำหรับสิ่งที่สามารถตรวจสอบได้ในขณะที่คุณพิมพ์ (อินพุตตัวเลขตัวอักษร) แต่จะไม่ทำงานสำหรับสิ่งที่ควรตรวจสอบความถูกต้องเมื่อผู้ใช้ป้อนข้อมูลเสร็จแล้ว (ที่อยู่อีเมล)
ปีเตอร์ Ajtai

คุณจะกระตุ้น Toast นั้นได้อย่างไร? ตัวกรองป้องกันไม่ให้นักดูข้อความใด ๆ ตอบโต้ ... บางทีด้วย onKeyListener
ช่วง

ฉันเรียกใช้ Toast ด้วยเงื่อนไข IF จากเมธอด filter () (ในคลาส InputFilter)
Moisés

6

ฉันจำเป็นต้องทำการตรวจสอบความถูกต้องของข้อมูลภายในและไม่ทำการตรวจสอบความถูกต้องระหว่างเขตเพื่อทดสอบว่าค่าของฉันเป็นค่าเลขทศนิยมที่ไม่ได้ลงนามในกรณีหนึ่งและลงนามค่าจุดลอยตัวในอีก นี่คือสิ่งที่ดูเหมือนจะทำงานให้ฉัน:

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

หมายเหตุคุณต้องไม่มีช่องว่างภายใน "numberSigned | numberDecimal" ตัวอย่างเช่น: "numberSigned | numberDecimal" จะไม่ทำงาน ฉันไม่แน่ใจว่าทำไม


5

สิ่งนี้ดูมีแนวโน้มมากและสิ่งที่เอกสารสั่งให้ฉัน:

EditText Validator

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

เครื่องมือตรวจสอบที่กำหนดเองรวมทั้งสิ่งเหล่านี้ในตัว:

  • regexp : สำหรับ regexp ที่กำหนดเอง
  • ตัวเลข : สำหรับฟิลด์ตัวเลขเท่านั้น
  • alpha : สำหรับฟิลด์ alpha only
  • ตัวอักษรและตัวเลข : เดาอะไร
  • personName : ตรวจสอบว่าข้อความที่ป้อนเป็นชื่อหรือนามสกุล
  • personFullName : ตรวจสอบว่าค่าที่ป้อนเป็นชื่อเต็มแบบสมบูรณ์หรือไม่
  • อีเมล : ตรวจสอบว่าฟิลด์เป็นอีเมลที่ถูกต้อง
  • creditCard : ตรวจสอบว่าฟิลด์มีบัตรเครดิตที่ถูกต้องโดยใช้อัลกอริทึม Luhn
  • โทรศัพท์ : ตรวจสอบว่าฟิลด์มีหมายเลขโทรศัพท์ที่ถูกต้อง
  • domainName : ตรวจสอบว่าฟิลด์นั้นมีชื่อโดเมนที่ถูกต้อง (ผ่านการทดสอบในระดับ API <8 เสมอ)
  • ipAddress : ตรวจสอบว่าฟิลด์มีที่อยู่ IP ที่ถูกต้อง
  • webUrl : ตรวจสอบว่าฟิลด์มี URL ที่ถูกต้อง (ผ่านการทดสอบในระดับ API <8 เสมอ)
  • วันที่ : ตรวจสอบว่าฟิลด์เป็นรูปแบบวันที่ / วันที่ถูกต้อง (หากมีการตั้งค่า customFormat ให้ตรวจสอบกับ customFormat)
  • nocheck : มันไม่ได้ตรวจสอบอะไรนอกจากความว่างเปล่าของสนาม

2

ในไฟล์ main.xml

คุณสามารถใส่ attrubute ต่อไปนี้เพื่อตรวจสอบเพียงตัวอักษรตัวอักษรที่สามารถยอมรับได้ใน edittext

ทำเช่นนี้ :

  android:entries="abcdefghijklmnopqrstuvwxyz"

2

คุณสามารถรับพฤติกรรมที่ต้องการได้โดยการฟังเมื่อผู้ใช้กดปุ่ม "เสร็จสิ้น" บนแป้นพิมพ์และเช็คเอาต์เคล็ดลับอื่น ๆ เกี่ยวกับการทำงานกับ EditText ในโพสต์ของฉัน"การตรวจสอบแบบฟอร์ม Android - วิธีที่ถูกต้อง"

รหัสตัวอย่าง:

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

สำหรับการตรวจสอบอีเมลและรหัสผ่านลอง

  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

ฉันได้สร้างไลบรารีนี้สำหรับ android ที่คุณสามารถตรวจสอบการออกแบบวัสดุ EditText ข้างในและ EditTextLayout ได้อย่างง่ายดายเช่นนี้:

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

จากนั้นคุณสามารถใช้มันเช่นนี้:

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

จากนั้นคุณสามารถตรวจสอบว่ามันถูกต้องเช่นนี้:

    ageSmartEditText.check()

สำหรับตัวอย่างเพิ่มเติมและการปรับแต่งให้ตรวจสอบที่เก็บ https://github.com/TeleClinic/SmartEditText

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.