6

I want to filter the input of an EditText, only digits and letters are allowed, first I use TextWatcher to deal with the last input character, but when you move the cursor or you past some content to the EditText, this method failed, now I want to know is there a way to filter the illegal input and give the user a feedback.

twlkyao
  • 14,302
  • 7
  • 27
  • 44

3 Answers3

15

Add InputFilter to your EditText & provide a Toast for user . This code snippet will help you.

 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))) { // Accept only letter & digits ; otherwise just return
                            Toast.makeText(context,"Invalid Input",Toast.LENGTH_SHORT).show();
                            return "";
                        }
                    }
                    return null;
                }

            };

        editText.setFilters(new InputFilter[] { filter });
Don Chakkappan
  • 7,397
  • 5
  • 44
  • 59
6

Have you tried the xml way? It will look something like this

<EditText 
  android:id="@+id/editText"
  android:inputType="text" 
  android:digits="0,1,2,3,4,5,6,7,8,9,*,qwertzuiopasdfghjklyxcvbnm" 
  android:hint="Only letters and numbers allowed.."
/>
Bidhan
  • 10,607
  • 3
  • 39
  • 50
  • This method has no feedback. – twlkyao May 15 '15 at 12:27
  • There is hint however. What kind of feedback are you looking for? A toast message? – Bidhan May 15 '15 at 12:29
  • This is awesome. I'm pretty sure if you're entering for example a telephone it's pretty obvious if only numbers and - work or something like that. No feedback needed. – csga5000 Apr 14 '16 at 05:17
  • 2
    Commas "," are not necessary. You can write `android:digits="0123456789*qwertzuiopasdfghjklyxcvbnm"` – Rafa0809 Oct 25 '16 at 23:47
  • i want to use alphabets digits and spaces then what to do? @Rafa0809 – Shashwat Gupta Aug 01 '17 at 10:10
  • 1
    @ĜüptåŠhãsĥwæt Try this: android:digits="0123456789abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ " – Rafa0809 Aug 01 '17 at 11:38
  • @Rafa0809 I have tried this but it doesn't take spaces – Shashwat Gupta Aug 01 '17 at 13:32
  • Have you ensured you included the space in the middle of the android:digits? Otherwise the problem is not focused on the android:digits. Take a look at this post: https://stackoverflow.com/questions/26057279/making-an-edittext-field-accept-only-letters-and-white-spaces-in-android – Rafa0809 Aug 02 '17 at 08:48
6

Work on all Android Versions:

public static InputFilter getOnlyCharactersFilter() {
    return getCustomInputFilter(true, false, false);
}

public static InputFilter getCharactersAndDigitsFilter() {
    return getCustomInputFilter(true, true, false);
}

public static InputFilter getCustomInputFilter(final boolean allowCharacters, final boolean allowDigits, final boolean allowSpaceChar) {
    return 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)) {
                    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) {
            if (Character.isLetter(c) && allowCharacters) {
                return true;
            }
            if (Character.isDigit(c) && allowDigits) {
                return true;
            }
            if (Character.isSpaceChar(c) && allowSpaceChar) {
                return true;
            }
            return false;
        }
    };
}

Now you can use this filer like:

 //Accept Characters Only
edit_text.setFilters(new InputFilter[]{getOnlyCharactersFilter()});

//Accept Digits and Characters
edit_text.setFilters(new InputFilter[]{getCharactersAndDigitsFilter()});

//Accept Digits and Characters and SpaceBar
edit_text.setFilters(new InputFilter[]{getCustomInputFilter(true,true,true)});
Salam El-Banna
  • 3,784
  • 1
  • 22
  • 34