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


171

ฉันต้องการ จำกัด ตัวอักษรไว้ที่ 0-9, az, AZ และ spacebar เท่านั้น การตั้งค่าประเภทอินพุตฉันสามารถ จำกัด ตัวเลขได้ แต่ฉันไม่สามารถหาวิธีของ Inputfilter ในการดูเอกสาร

คำตอบ:


186

ฉันพบสิ่งนี้ในฟอรัมอื่น ทำงานเหมือนแชมป์

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++) {
            if (!Character.isLetterOrDigit(source.charAt(i))) {
                return "";
            }
        }
        return null;
    }
};
edit.setFilters(new InputFilter[] { filter });

58
ที่จริงแล้วมันใช้ไม่ได้กับ Android รุ่นใหม่กว่า (เช่น 4.0+) พวกเขาแนะนำคำแนะนำพจนานุกรมไว้เหนือแป้นพิมพ์ เมื่อคุณพิมพ์คำทั่วไป (สมมติว่า "the") ตามด้วยอักขระที่ผิดกฎหมายสำหรับตัวกรองนี้ (พูดว่า "-") คำทั้งหมดจะถูกลบและหลังจากคุณพิมพ์อักขระอื่น (แม้แต่คำที่อนุญาตเช่น "blah") ตัวกรองคืนค่า "" และไม่มีตัวอักษรปรากฏขึ้นในฟิลด์ นี่เป็นเพราะวิธีการที่ได้รับ SpannableStringBuilder ในพารามิเตอร์แหล่งที่มาด้วย "the-blah" ในนั้นและพารามิเตอร์เริ่มต้น / สิ้นสุดซึ่งประกอบไปด้วยสตริงการป้อนข้อมูลทั้งหมด ... ดูคำตอบของฉันสำหรับทางออกที่ดีกว่า
Łukasz Sromek

4
ในตัวอย่างนั้นมันจะส่งคืน "" ฉันคิดว่าควรส่งคืนข้อความที่ควรแสดง เช่นคุณควรลบอักขระที่ผิดกฎหมายและคืนสตริงที่คุณต้องการแสดง developer.android.com/reference/android/widget/… , android.view.KeyEvent)
Andrew Mackenzie

+1 ตอบกลับเป็นอย่างดี Character.isLetterOrDigit () วิธีการทั้งหมดนี้มีประโยชน์มาก
Atul Bhardwaj

@AndrewMackenzie หากอักขระป้อนเช่นเครื่องหมายจุลภาค ',' ซึ่งไม่ถูกกฎหมายและฉันต้องการลบออกวิธีการแก้ไขรหัสข้างต้น
twlkyao

! Character.isLetterOrDigit (source.charAt (i)) &&! Character.isSpaceChar (source.charAt (i)) เพื่ออนุญาตให้มีที่ว่าง
Leon

139

InputFilterมีความซับซ้อนเล็กน้อยในรุ่น Android ที่แสดงคำแนะนำพจนานุกรม บางครั้งคุณได้รับ a SpannableStringBuilderซึ่งบางครั้งก็ธรรมดาStringในsourceพารามิเตอร์

ต่อไปนี้InputFilterควรทำงาน อย่าลังเลที่จะปรับปรุงรหัสนี้!

new InputFilter() {
    @Override
    public CharSequence filter(CharSequence source, int start, int end,
            Spanned dest, int dstart, int dend) {

        if (source instanceof SpannableStringBuilder) {
            SpannableStringBuilder sourceAsSpannableBuilder = (SpannableStringBuilder)source;
            for (int i = end - 1; i >= start; i--) { 
                char currentChar = source.charAt(i);
                 if (!Character.isLetterOrDigit(currentChar) && !Character.isSpaceChar(currentChar)) {    
                     sourceAsSpannableBuilder.delete(i, i+1);
                 }     
            }
            return source;
        } else {
            StringBuilder filteredStringBuilder = new StringBuilder();
            for (int i = start; i < end; i++) { 
                char currentChar = source.charAt(i);
                if (Character.isLetterOrDigit(currentChar) || Character.isSpaceChar(currentChar)) {    
                    filteredStringBuilder.append(currentChar);
                }     
            }
            return filteredStringBuilder.toString();
        }
    }
}

2
มีเหตุผลทำไมคุณไม่ต้องการเรียงแหล่งที่มา? คุณเห็นสิ่งผิดปกติในการทำสิ่งนี้หรือไม่ (เพื่ออนุญาตให้ใช้ตัวอักษรและตัวเลขรวมถึงอักขระพิเศษบางตัวเท่านั้น): String replacement = source.subSequence(start, end).toString(); return replacement.replaceAll("[^A-Za-z0-9_\\-@]", "");
สแปลช

3
สิ่งนี้ไม่คำนึงถึงปัญหาที่ข้อความคำแนะนำพจนานุกรมซ้ำปรากฏขึ้น @serwus ระบุว่าในคำตอบของพวกเขา โดยทั่วไปคุณควรส่งคืน null หากไม่มีการแก้ไขใด ๆ ในทั้งสองกรณี
hooby3dfx

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

3
ด้วยเหตุผลบางอย่างเมื่อsource instanceof SpannableStringBuilderเข้าABให้ฉันAABเหมือนเมื่อลองคำตอบก่อนหน้า โชคดีที่ฉันสามารถแก้ไขได้โดยใช้ @florian solution ด้านล่าง
Guillaume

1
@ hooby3dfx ถูกต้องอย่างแน่นอน ในขณะที่มันจัดการเพื่อให้ได้สตริงที่ถูกต้องในที่สุดมันก็เลอะเมื่อคุณใช้พจนานุกรม / คำสมบูรณ์
Aravind

107

ง่ายกว่ามาก:

<EditText
    android:inputType="text"
    android:digits="0,1,2,3,4,5,6,7,8,9,*,qwertzuiopasdfghjklyxcvbnm" />

9
ขณะนี้ดูเหมือนว่าคำตอบที่สมบูรณ์มีปัญหาตามเอกสาร: "สำหรับการใช้งานทั้งหมดของ KeyListener คลาสนี้เกี่ยวข้องกับคีย์บอร์ดฮาร์ดแวร์เท่านั้นวิธีการอินพุตซอฟต์แวร์ไม่มีข้อผูกมัดในการเรียกใช้วิธีในคลาสนี้ ฉันคิดว่า InputFilter น่าจะดีกว่าแม้ว่าจะซับซ้อนกว่า
Craig B

19
น่ากลัวโซลูชั่นเพียงแค่ต้องการเพิ่มคุณไม่จำเป็นต้องให้","ในระหว่าง คุณสามารถใช้สิ่งนี้"0123456789qwertzuiopasdfghjklyxcvbnmQWERTZUIOPASDFGHJKLYXCVBNM"
DeltaCap019

26
ไม่ใช่โซลูชันหลายภาษา
AAverin

หากคุณวางแผนที่จะใช้การแปลในแอปของคุณ อย่าใช้โซลูชันนี้!
grantespo

ดูเหมือนว่าสิ่งนี้จะไม่สามารถทำงานได้imeOptions="actionNext"ฯลฯ
Pete Doyle

68

คำตอบที่โพสต์ไม่ได้ผลสำหรับฉัน ฉันมาพร้อมทางออกของตัวเอง:

InputFilter filter = new InputFilter() {
    @Override
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
        boolean keepOriginal = true;
        StringBuilder sb = new StringBuilder(end - start);
        for (int i = start; i < end; i++) {
            char c = source.charAt(i);
            if (isCharAllowed(c)) // put your condition here
                sb.append(c);
            else
                keepOriginal = false;
        }
        if (keepOriginal)
            return null;
        else {
            if (source instanceof Spanned) {
                SpannableString sp = new SpannableString(sb);
                TextUtils.copySpansFrom((Spanned) source, start, sb.length(), null, sp, 0);
                return sp;
            } else {
                return sb;
            }           
        }
    }

    private boolean isCharAllowed(char c) {
        return Character.isLetterOrDigit(c) || Character.isSpaceChar(c);
    }
}
editText.setFilters(new InputFilter[] { filter });

3
นี่เป็นคำตอบเดียวที่จริง ๆ แล้วมีแนวทางที่ถูกต้องในการป้องกันการทำซ้ำข้อความจากคำแนะนำในพจนานุกรม! Upvote!
hooby3dfx

4
สิ่งเดียวที่EditTextสามารถมีตัวกรองของตัวเองได้แล้วเช่นตัวกรองความยาว ดังนั้นแทนที่จะแค่ลบล้างตัวกรองคุณน่าจะต้องการเพิ่มตัวกรองของคุณไปยังตัวกรองที่มีอยู่แล้ว
Aleks N.

ยังคงเป็นปัจจุบันหรือไม่? สำหรับฉัน Android 6.0.1 มันใช้งานได้บนแป้นพิมพ์บนหน้าจอ
XxGoliathusxX

2
ปัญหาเล็กน้อยกับคำตอบนี้ (หรือวิธีการทำงานของกลไกการป้อนข้อมูลของ Android) คือบางครั้ง backspace นั้นปรากฏแก่ผู้ใช้ว่าไม่สามารถทำงานได้เนื่องจาก backspacing ผ่านอักขระที่ไม่ถูกต้องที่ป้อนไว้ก่อนหน้านี้ที่ยังคงอยู่ในบัฟเฟอร์ต้นฉบับ
jk7

1
ปัญหาเช่นเดียวกับวิธีการแก้ปัญหาของŁukasz Sromek: อักขระที่ไม่ถูกต้องหลังจากเว้นวรรคจะถูกแทนที่ด้วยช่องว่าง
Ingo Schalk-Schupp

25

ใช้สิ่งนี้ทำงานได้ 100% ความต้องการของคุณและง่ายมาก

<EditText
android:inputType="textFilter"
android:digits="@string/myAlphaNumeric" />

ใน strings.xml

<string name="myAlphaNumeric">abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789</string>

15

เพื่อหลีกเลี่ยงอักขระพิเศษในประเภทอินพุต

public static InputFilter filter = new InputFilter() {
    @Override
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
        String blockCharacterSet = "~#^|$%*!@/()-'\":;,?{}=!$^';,?×÷<>{}€£¥₩%~`¤♡♥_|《》¡¿°•○●□■◇◆♧♣▲▼▶◀↑↓←→☆★▪:-);-):-D:-(:'(:O 1234567890";
        if (source != null && blockCharacterSet.contains(("" + source))) {
            return "";
        }
        return null;
    }
};

คุณสามารถตั้งค่าตัวกรองเป็นข้อความแก้ไขของคุณด้านล่าง

edtText.setFilters(new InputFilter[] { filter });

@sathya คุณ wc มีความสุขที่จะช่วยคุณ :)

1
ไม่บล็อกอักขระเหล่านี้ใด ๆ ㋡㋛☺☹☻〠シッツヅÜ 〲 〴 ϡٿت⍡⍢⍣
Anarchofascist

7

นอกจากคำตอบที่ยอมรับแล้วยังสามารถใช้เช่น: android:inputType="textCapCharacters"เป็นคุณสมบัติ<EditText>เพื่อรับเฉพาะอักษรตัวพิมพ์ใหญ่ (และตัวเลข)


5
android: inputType = "textCapCharacters" ไม่ได้ จำกัด การใช้งานตัวอักษรอื่น ๆ เช่น '., - "ฯลฯ
Tvd

นอกจากนี้ยังเป็นเพียงคำใบ้ถึงวิธีการป้อนข้อมูล มันไม่ได้ จำกัด สิ่งที่ตัวละครได้รับอนุญาตให้ป้อน
dcow

5

ด้วยเหตุผลบางอย่างตัวสร้างคลาส android.text.LoginFilter มีการกำหนดขอบเขตแพ็กเกจดังนั้นคุณจึงไม่สามารถขยายได้โดยตรง (แม้ว่าจะเหมือนกับโค้ดนี้) แต่คุณสามารถขยาย LoginFilter.UsernameFilterGeneric! แล้วคุณมีสิ่งนี้:

class ABCFilter extends LoginFilter.UsernameFilterGeneric {
    public UsernameFilter() {
        super(false); // false prevents not-allowed characters from being appended
    }

    @Override
    public boolean isAllowed(char c) {
        if ('A' <= c && c <= 'C')
            return true;
        if ('a' <= c && c <= 'c')
            return true;

        return false;
    }
}

นี้ไม่ได้มีการบันทึกไว้จริงๆ แต่มันก็เป็นส่วนหนึ่งของ lib หลักและแหล่งที่มาตรงไปตรงมา ฉันใช้มันมาระยะหนึ่งแล้วจนถึงตอนนี้ก็ไม่มีปัญหาแม้ว่าฉันจะยอมรับว่าฉันไม่ได้ลองทำอะไรที่ซับซ้อนเกี่ยวกับ spannables


5

มันถูกต้องวิธีที่ดีที่สุดในการแก้ไขมันใน XML Layout เองโดยใช้:

<EditText
android:inputType="text"
android:digits="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" />

Florian Fröhlichเป็นผู้ชี้ให้เห็นอย่างถูกต้องมันทำงานได้ดีสำหรับการดูข้อความ

<TextView
android:inputType="text"
android:digits="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" />

เพียงแค่คำเตือนตัวละครที่กล่าวถึงในandroid:digitsจะปรากฏขึ้นเท่านั้นดังนั้นโปรดระวังอย่าพลาดชุดอักขระใด ๆ :)


คุณต้องกำหนด inputType = "textFilter" จากนั้นจะสามารถทำงานได้อย่างถูกต้องเท่านั้น
Shreyash Mahajan

@ShreyashMahajan มันขึ้นอยู่กับแอพของอุปกรณ์ / คีย์บอร์ดหรือไม่ ในกรณีของฉันinputTypeไม่มีผลต่อการกรอง
CoolMind

4

วิธีแก้ปัญหาอย่างง่ายนี้ทำงานสำหรับฉันเมื่อฉันต้องการป้องกันไม่ให้ผู้ใช้ป้อนสตริงว่างใน EditText แน่นอนคุณสามารถเพิ่มตัวอักษรเพิ่มเติมได้:

InputFilter textFilter = new InputFilter() {

@Override

public CharSequence filter(CharSequence c, int arg1, int arg2,

    Spanned arg3, int arg4, int arg5) {

    StringBuilder sbText = new StringBuilder(c);

    String text = sbText.toString();

    if (text.contains(" ")) {    
        return "";   
    }    
    return c;   
    }   
};

private void setTextFilter(EditText editText) {

    editText.setFilters(new InputFilter[]{textFilter});

}

จะโทรหาโซลูชันนี้ได้อย่างไร
zeeks

1

หากคุณ subclass InputFilter คุณสามารถสร้าง InputFilter ของคุณเองที่จะกรองอักขระที่ไม่ใช่ตัวอักษรและตัวเลข

อินเทอร์เฟซ InputFilter มีหนึ่งวิธี filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend)และให้ข้อมูลทั้งหมดที่คุณต้องรู้เกี่ยวกับตัวละครที่ถูกป้อนลงใน EditText ที่ได้รับมอบหมาย

เมื่อคุณสร้าง InputFilter ของคุณเองแล้วคุณสามารถกำหนดให้กับ EditText ได้โดยเรียก setFilters (... )

http://developer.android.com/reference/android/text/InputFilter.html#filter(java.lang.CharSequence , int, int, android.text.Spanned, int, int)


1

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

แหล่งที่มาเติบโตตามคำแนะนำที่เพิ่มขึ้นดังนั้นเราต้องดูว่ามีตัวละครกี่ตัวที่คาดหวังให้เราแทนที่ก่อนที่เราจะคืนสิ่งใด

หากเราไม่มีอักขระที่ไม่ถูกต้องให้ส่งคืน null เพื่อให้การแทนที่เริ่มต้นเกิดขึ้น

มิฉะนั้นเราจะต้องแยกอักขระที่ถูกต้องออกจากสตริงย่อยที่จริงจะถูกวางลงใน EditText

InputFilter filter = new InputFilter() { 
    public CharSequence filter(CharSequence source, int start, int end, 
    Spanned dest, int dstart, int dend) { 

        boolean includesInvalidCharacter = false;
        StringBuilder stringBuilder = new StringBuilder();

        int destLength = dend - dstart + 1;
        int adjustStart = source.length() - destLength;
        for(int i=start ; i<end ; i++) {
            char sourceChar = source.charAt(i);
            if(Character.isLetterOrDigit(sourceChar)) {
                if(i >= adjustStart)
                     stringBuilder.append(sourceChar);
            } else
                includesInvalidCharacter = true;
        }
        return includesInvalidCharacter ? stringBuilder : null;
    } 
}; 

1

เพื่อป้องกันคำใน edittext สร้างคลาสที่คุณสามารถใช้ได้ทุกเวลา

public class Wordfilter implements InputFilter
{
    @Override
    public CharSequence filter(CharSequence source, int start, int end,Spanned dest, int dstart, int dend) {
        // TODO Auto-generated method stub
        boolean append = false;
        String text = source.toString().substring(start, end);
        StringBuilder str = new StringBuilder(dest.toString());
        if(dstart == str.length())
        {
            append = true;
            str.append(text);
        }
        else
            str.replace(dstart, dend, text);
        if(str.toString().contains("aaaaaaaaaaaa/*the word here*/aaaaaaaa"))
        {
            if(append==true)
                return "";
            else
                return dest.subSequence(dstart, dend);
        }
        return null;
    }
}

1

เพิ่มเป็นstrings.xml:

<string name="vin_code_mask">0123456789abcdefghjklmnprstuvwxyz</string>

XML :

android:digits="@string/vin_code_mask"

รหัสใน Kotlin:

edit_text.filters += InputFilter { source, start, end, _, _, _ ->
    val mask = getString(R.string.vin_code_mask)
    for (i in start until end) {
        if (!mask.contains(source[i])) {
            return@InputFilter ""
        }
    }
    null
}

แปลก แต่ก็ใช้งานได้ดีกับคีย์บอร์ดนุ่มของอีมูเลเตอร์

คำเตือน! รหัสต่อไปนี้จะกรองตัวอักษรและสัญลักษณ์อื่น ๆ ทั้งหมดยกเว้นตัวเลขสำหรับแป้นพิมพ์ซอฟต์แวร์ เฉพาะแป้นพิมพ์ดิจิทัลเท่านั้นที่จะปรากฏบนสมาร์ทโฟน

edit_text.keyListener = DigitsKeyListener.getInstance(context.getString(R.string.vin_code_mask))

ฉันก็มักจะตั้งmaxLength, ,filtersinputType


1

นี่เป็นเธรดเก่า แต่โซลูชันที่มีวัตถุประสงค์ทั้งหมดมีปัญหา (ขึ้นอยู่กับอุปกรณ์ / รุ่น Android / คีย์บอร์ด)

แนวทางที่แตกต่าง

ดังนั้นในที่สุดฉันก็ไปด้วยวิธีที่แตกต่างแทนที่จะใช้การInputFilterใช้งานที่มีปัญหาฉันกำลังใช้TextWatcherและTextChangedListenerของEditTextของ

รหัสเต็ม (ตัวอย่าง)

editText.addTextChangedListener(new TextWatcher() {

    @Override
    public void afterTextChanged(Editable editable) {
        super.afterTextChanged(editable);

        String originalText = editable.toString();
        int originalTextLength = originalText.length();
        int currentSelection = editText.getSelectionStart();

        // Create the filtered text
        StringBuilder sb = new StringBuilder();
        boolean hasChanged = false;
        for (int i = 0; i < originalTextLength; i++) {
            char currentChar = originalText.charAt(i);
            if (isAllowed(currentChar)) {
                sb.append(currentChar);
            } else {
                hasChanged = true;
                if (currentSelection >= i) {
                    currentSelection--;
                }
            }
        }

        // If we filtered something, update the text and the cursor location
        if (hasChanged) {
            String newText = sb.toString();
            editText.setText(newText);
            editText.setSelection(currentSelection);
        }
    }

    private boolean isAllowed(char c) {
        // TODO: Add the filter logic here
        return Character.isLetter(c) || Character.isSpaceChar(c);
    }
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        // Do Nothing
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        // Do Nothing
    }
});

เหตุผลInputFilterไม่ได้เป็นทางออกที่ดีใน Android เพราะมันขึ้นอยู่กับการใช้แป้นพิมพ์ EditTextอินพุตแป้นพิมพ์จะถูกกรองก่อนที่จะป้อนข้อมูลที่ถูกส่งไปยัง แต่เนื่องจากคีย์บอร์ดบางตัวมีการใช้งานที่แตกต่างกันสำหรับการInputFilter.filter()เรียกใช้นี่เป็นปัญหา

ในทางกลับกันTextWatcherไม่สนใจเกี่ยวกับการใช้งานคีย์บอร์ดมันช่วยให้เราสร้างโซลูชันที่ง่ายและให้แน่ใจว่ามันจะทำงานบนอุปกรณ์ทั้งหมด


onTextChangedเพียงแค่ความต้องการpublic voidในด้านหน้าของมัน
Andy

ขอบคุณสำหรับความคิดเห็น แก้ไขแล้ว.
Eyal Biran

1

ฉันทำสิ่งนี้เพื่อให้ง่าย:

edit_text.filters = arrayOf(object : InputFilter {
    override fun filter(
        source: CharSequence?,
        start: Int,
        end: Int,
        dest: Spanned?,
        dstart: Int,
        dend: Int
    ): CharSequence? {
        return source?.subSequence(start, end)
            ?.replace(Regex("[^A-Za-z0-9 ]"), "")
    }
})

ด้วยวิธีนี้เราจะแทนที่ตัวละครที่ไม่ต้องการทั้งหมดในส่วนใหม่ของสตริงต้นฉบับด้วยสตริงว่าง

edit_textตัวแปรเป็นEditTextวัตถุที่เราหมายถึง

kotlinรหัสถูกเขียนใน


1
ขอบคุณ! วิธีนี้ใช้ได้ดีเมื่อพิมพ์รวมถึงการวางข้อความ
CoolMind

0

setOnKeyListenerมันเป็นไปได้ที่จะใช้ ในวิธีนี้เราสามารถปรับแต่งอินพุตedittext!


0

นี่คือวิธีที่ฉันสร้างตัวกรองสำหรับฟิลด์ชื่อในแก้ไขข้อความ (ตัวอักษรตัวแรกคือ CAPS และอนุญาตให้เว้นวรรคเดียวหลังจากทุกคำ

public void setNameFilter() {
    InputFilter filter = new InputFilter() {
        @RequiresApi(api = Build.VERSION_CODES.KITKAT)
        public CharSequence filter(CharSequence source, int start, int end,
                                   Spanned dest, int dstart, int dend) {
            for (int i = start; i < end; i++) {
                if (dend == 0) {
                    if (Character.isSpaceChar(source.charAt(i)) ||
                            !Character.isAlphabetic(source.charAt(i))) {
                        return Constants.Delimiter.BLANK;
                    } else {
                        return String.valueOf(source.charAt(i)).toUpperCase();
                    }
                } else if (Character.isSpaceChar(source.charAt(i)) &&
                        String.valueOf(dest).endsWith(Constants.Delimiter.ONE_SPACE)) {
                    return Constants.Delimiter.BLANK;
                } else if ((!Character.isSpaceChar(source.charAt(i)) &&
                        !Character.isAlphabetic(source.charAt(i)))) {
                    return Constants.Delimiter.BLANK;
                }
            }
            return null;
        }
    };
    editText.setFilters(new InputFilter[]{filter, new InputFilter.LengthFilter(Constants.Length.NAME_LENGTH)});
}

ค่าคงที่ส่วนที่เหลือ BLANK ยังไม่เป็นที่รู้จัก
CoolMind

0

ฉันมีคำตอบเดียวกันใน Kotlin:

/**
 * Returns the filter of the editText'es CharSequence value when [filterType] is:
 * 1 -> letters; 2 -> letters and digits; 3 -> digits;
 * 4 -> digits and dots
 */
class InputFilterAlphanumeric(private val filterType: Int): InputFilter {
    override fun filter(source: CharSequence?, start: Int, end: Int, dest: Spanned?, dstart: Int, dend: Int): CharSequence {
        (source as? SpannableStringBuilder)?.let {sourceAsSpannableBuilder  ->
            for (i in (end - 1) downTo start) {
                val currentChar = source[i]
                when(filterType) {
                    1 -> {
                        if (!currentChar.isLetter() && !currentChar.isWhitespace()) {
                            sourceAsSpannableBuilder.delete(i, i + 1)
                        }
                    }
                    2 -> {
                        if (!currentChar.isLetterOrDigit() && !currentChar.isWhitespace()) {
                            sourceAsSpannableBuilder.delete(i, i + 1)
                        }
                    }
                    3 -> {
                        if (!currentChar.isDigit()) {
                            sourceAsSpannableBuilder.delete(i, i + 1)
                        }
                    }
                    4 -> {
                        if (!currentChar.isDigit() || !currentChar.toString().contains(".")) {
                            sourceAsSpannableBuilder.delete(i, i + 1)
                        }
                    }
                }
            }
            return source
        } ?: run {
            val filteredStringBuilder = StringBuilder()
            for (i in start until end) {
                val currentChar = source?.get(i)
                when(filterType) {
                    1 -> {
                        if (currentChar?.isLetter()!! || currentChar.isWhitespace()) {
                            filteredStringBuilder.append(currentChar)
                        }
                    }
                    2 -> {
                        if (currentChar?.isLetterOrDigit()!! || currentChar.isWhitespace()) {
                            filteredStringBuilder.append(currentChar)
                        }
                    }
                    3 -> {
                        if (currentChar?.isDigit()!!) {
                            filteredStringBuilder.append(currentChar)
                        }
                    }
                    4 -> {
                        if (currentChar?.isDigit()!! || currentChar.toString().contains(".")) {
                            filteredStringBuilder.append(currentChar)
                        }
                    }
                }
            }
            return filteredStringBuilder
        }
    }
}

และรับคลาสด้วยฟังก์ชัน Extension:

fun EditText.filterByDataType(filterType: Int) {
    this.filters = arrayOf<InputFilter>(InputFilterAlphanumeric(filterType))
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.