81

How can I restrict an EditText to accept only alphanumeric characters, with both lowercase and uppercase characters showing as uppercase in the EditText?

<EditText
    android:id="@+id/userInput"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:inputType="textMultiLine"
    android:minLines="3" >

    <requestFocus />
</EditText>

If a user types in lowercase "abcd", the EditText should automatically show uppercase "ABCD" without needing to restrict the keyboard to uppercase.

Steven Byle
  • 13,149
  • 4
  • 45
  • 57
user3472001
  • 855
  • 2
  • 7
  • 9
  • editText.setKeyListener(DigitsKeyListener.getInstance("abcdefghijklmnopqrstuvwxyz1234567890 ")); – Zar E Ahmer May 29 '18 at 09:53
  • Does this answer your question? [Validation allow only number and characters in edit text in android](https://stackoverflow.com/questions/14192199/validation-allow-only-number-and-characters-in-edit-text-in-android) – Josh Correia Jul 17 '20 at 20:15

14 Answers14

144

In the XML, add this:

 android:digits="abcdefghijklmnopqrstuvwxyz1234567890 "
Hashir Sheikh
  • 1,811
  • 1
  • 14
  • 14
36

How to restrict the EditText to accept only alphanumeric characters only so that whatever lower case or upper case key that the user is typing, EditText will show upper case

The InputFilter solution works well, and gives you full control to filter out input at a finer grain level than android:digits. The filter() method should return null if all characters are valid, or a CharSequence of only the valid characters if some characters are invalid. If multiple characters are copied and pasted in, and some are invalid, only the valid characters should be kept.

public static class AlphaNumericInputFilter implements InputFilter {
    public CharSequence filter(CharSequence source, int start, int end,
            Spanned dest, int dstart, int dend) {

        // Only keep characters that are alphanumeric
        StringBuilder builder = new StringBuilder();
        for (int i = start; i < end; i++) {
            char c = source.charAt(i);
            if (Character.isLetterOrDigit(c)) {
                builder.append(c);
            }
        }

        // If all characters are valid, return null, otherwise only return the filtered characters
        boolean allCharactersValid = (builder.length() == end - start);
        return allCharactersValid ? null : builder.toString();
    }
}

Also, when setting your InputFilter, you must make sure not to overwrite other InputFilters set on your EditText; these could be set in XML, like android:maxLength. You must also consider the order that the InputFilters are set, they are applied in that order. Luckily, InputFilter.AllCaps already exists, so that applied with our alphanumeric filter will keep all alphanumeric text, and convert it to uppercase.

    // Apply the filters to control the input (alphanumeric)
    ArrayList<InputFilter> curInputFilters = new ArrayList<InputFilter>(Arrays.asList(editText.getFilters()));
    curInputFilters.add(0, new AlphaNumericInputFilter());
    curInputFilters.add(1, new InputFilter.AllCaps());
    InputFilter[] newInputFilters = curInputFilters.toArray(new InputFilter[curInputFilters.size()]);
    editText.setFilters(newInputFilters);
Steven Byle
  • 13,149
  • 4
  • 45
  • 57
  • 2
    This should be the accepted answer. I have tried the suggested solutions on this and other pages and only this solution covers all my devices perfectly (Samsung being a particularly annoying one). Some gave me ONLY number input, some just failed to type anything complaining about the initial length of 0 characters on input etc. i would also shorthand the set filters to `editText.setFilters(new InputFilter[]{new InputFilter.AllCaps(), alphanumericFilter});` – ZooS Jun 30 '16 at 09:12
  • @ZooS your shorthand would overwrite any existing `InputFilters` already on the `EditText`. Please *read* my explanation right above the code block, setting of the filter is done that way for very specific reasons. – Steven Byle Jun 30 '16 at 13:05
  • My bad, didn't quite read through the explanation, you are correct. This is teh best solution in my opinion. – ZooS Jul 01 '16 at 10:34
  • Didn't work. When the user inputs a non-valid character, the current text on the edit text is doubled !! – Felipe Ribeiro R. Magalhaes Mar 30 '17 at 02:07
  • 1
    The bug happens when you type two numbers in a row – Felipe Ribeiro R. Magalhaes Mar 30 '17 at 02:26
  • @FelipeRibeiroR.Magalhaes Double check your code. If you are having trouble, post a question. I have this code working in multiple production apps. – Steven Byle Mar 30 '17 at 13:17
  • This actually accepts another languages too, not only alphabets. – wonsuc Feb 27 '18 at 18:24
  • but it doesn't accept white space, I tried ```if (Character.isLetter(c) || Character.isSpaceChar(' ')) { builder.append(c); }``` but no luck – Ege Kuzubasioglu Jul 10 '18 at 07:36
  • also @FelipeRibeiroR.Magalhaes is right, when you type numbers it appends the current text to the current one, the reason is obviously Stupid Samsung and their horrible phones because it works on other brands – Ege Kuzubasioglu Jul 10 '18 at 08:14
  • I need to restrict the mathematical "pi" symbol which is there in google indic keyboard. how can i do that using this approach?? – Roohi Zuwairiyah Sep 18 '18 at 04:51
  • This answer works best. I added a Kotlin version similar to this approach here: https://stackoverflow.com/a/52712002/5652513. – methodsignature Oct 09 '18 at 01:09
  • "You must also consider the order that the InputFilters are set, they are applied in that order." - I fail to understand why the order is important ? – Goran Horia Mihail Feb 18 '20 at 11:37
  • 1
    @GoranHoriaMihail if you have multiple non-mutually exclusive filters, i.e. a length filter of 10 and an alphanumeric filter, you would want to apply the alphanumeric filter first, then the length of 10 filter. Otherwise, if the length filter is applied first, it would trim to 10, and then may remove more non alphanumeric characters when the alphanumeric filter is applied, incorrectly only applying the alphanumeric filter to the first 10 characters (rather than keeping up to 10 alphanumeric characters). This would come into play when a user pastes text into an EditText from say a PW manager. – Steven Byle Feb 19 '20 at 16:15
20

If you don't want much of customization a simple trick is actually from the above one with all characters you want to add in android:digits

android:digits="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"

This should work to accept alphanumeric values with Caps & Small letters.

Ajeet Singh
  • 417
  • 7
  • 23
12

Use this:

android:digits="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
android:inputType="textCapCharacters"

I tried using textAllCaps="true" as suggested in a comment of accepted answer to this question but it didn't work as expected.

thetanuj
  • 379
  • 2
  • 9
8

You do not want to write any regular expression for this you can just add XML properties to your Edit text

android:digits="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
android:inputType="textCapCharacters"

Tested Working Perfectly for PAN Card validation.

saigopi.me
  • 14,011
  • 2
  • 83
  • 54
6

try This:

private void addFilterToUserName()
    {

        sign_up_display_name_et.setFilters(new InputFilter[] {
                new InputFilter() {
                    public CharSequence filter(CharSequence src, int start,
                                               int end, Spanned dst, int dstart, int dend) {
                        if(src.equals("")){ // for backspace
                            return src;
                        }
                        if(src.toString().matches("[a-zA-Z 0-9]+")){
                            return src;
                        }
                        return "";
                    }
                }
        });
    }
Gal Rom
  • 6,221
  • 3
  • 41
  • 33
6

Minimalist Kotlin approach:

fun EditText.allowOnlyAlphaNumericCharacters() {
    filters = filters.plus(
        listOf(
            InputFilter { s, _, _, _, _, _->
                s.replace(Regex("[^A-Za-z0-9]"), "")
            },
            InputFilter.AllCaps()
        )
    )
}
methodsignature
  • 4,152
  • 2
  • 20
  • 21
  • this resulted in a weird bug where after typing something, the edittext is filled with random letters that can't be removed – Aba Feb 18 '20 at 08:25
  • try https://stackoverflow.com/a/68709480/4091268. Uodated version of above. – Idris Bohra Aug 09 '21 at 09:06
2

For that you need to create your custom Filter and set to your EditText like this.

This will convert your alphabets to uppercase automatically.

EditText editText = (EditText)findViewById(R.id.userInput);
InputFilter myFilter = new InputFilter() {

    @Override
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
        try {
            Character c = source.charAt(0);
            if (Character.isLetter(c) || Character.isDigit(c)) {
                return "" + Character.toUpperCase(c);
            } else {
                return "";
            }
        } catch (Exception e) {
        }
        return null;
    }
};
editText.setFilters(new InputFilter[] { myFilter });

No additional parameters to set in xml file.

Biraj Zalavadia
  • 28,348
  • 10
  • 61
  • 77
2
<EditText
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="PromoCode"
                    android:digits="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789,_,-"
                    android:inputType="text" />
Amir Dora.
  • 2,831
  • 4
  • 40
  • 61
2

I tried the solution by @methodSignature but as mentioned by @Aba it is generating the repeated/weird string. So modified it.

Kotlin:

fun EditText.allowOnlyAlphaNumericCharacters() {
    filters = arrayOf(
        InputFilter { src, start, end, dst, dstart, dend ->
            if (src.toString().matches(Regex("[a-zA-Z 0-9]+"))) {
                src
            } else ""
        }
    )
}
Pragnesh Ghoda シ
  • 8,318
  • 3
  • 25
  • 40
Idris Bohra
  • 354
  • 3
  • 6
1

This works for me:

android:inputType="textVisiblePassword"

xuxu
  • 6,374
  • 1
  • 17
  • 11
1

Programmatically, do this:

mEditText.setInputType(InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
mEditText.setFilters(new InputFilter[] {
    new InputFilter() {   
        @Override  
        public CharSequence filter(CharSequence input, int start, int end, Spanned dst, int dstart, int dend) { 
            if (input.length() > 0 && !Character.isLetterOrDigit(input.charAt(0))) {  
                // if not alphanumeric, disregard the latest input
                // by returning an empty string 
                return ""; 
            }
            return null;
        }  
    }, new InputFilter.AllCaps()
});

Note that the call to setInputType is necessary so that we are sure that the input variable is always the last character given by the user.

I have tried other solutions discussed here in SO. But many of them were behaving weird in some cases such as when you have Quick Period (Tap space bar twice for period followed by space) settings on. With this setting, it deletes one character from your input text. This code solves this problem as well.

user1506104
  • 6,554
  • 4
  • 71
  • 89
0
private static final int MAX_LENGTH =13;

et_ScanLotBrCode.setFilters(new InputFilter[]{new InputFilter.AllCaps(),new InputFilter.LengthFilter(MAX_LENGTH) });

add above code into activity or fragment, using this you can manage the length of input and uppercase letter.

Ragesh Pikalmunde
  • 1,333
  • 1
  • 20
  • 44
Sainath
  • 11
  • 1
  • 2
  • 2
    The question does not ask about limiting the length. It asks how to restrict the `EditText` to accept only alphanumeric characters and to display them in uppercase. – Puspam Jul 02 '20 at 09:55
-3

one line answer

XML Add this textAllCaps="true"

do this onCreate()

for lower case & upper case with allowing space

yourEditText.setKeyListener(DigitsKeyListener.getInstance("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890 "));

for lower case with allowing space (Required answer for this question)

yourEditText.setKeyListener(DigitsKeyListener.getInstance("abcdefghijklmnopqrstuvwxyz1234567890 "));

for upper case with allowing space

yourEditText.setKeyListener(DigitsKeyListener.getInstance("ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 "));
Tushar Narang
  • 1,997
  • 3
  • 21
  • 49