如何限制EditText只接受字母和数字字符

81

我该如何限制一个 EditText 只接受大小写字母和数字,并且在 EditText 中显示时,所有字符都显示为大写字母?

如何限制EditText只接受大小写字母和数字,并将所有字符显示为大写字母?

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

    <requestFocus />
</EditText>
如果用户输入小写的 "abcd",EditText 应该自动显示大写的 "ABCD",而不需要限制键盘为大写。

editText.setKeyListener(DigitsKeyListener.getInstance("abcdefghijklmnopqrstuvwxyz1234567890 ")); 编辑文本设置按键监听器(DigitsKeyListener),获取实例("abcdefghijklmnopqrstuvwxyz1234567890 ")。 - Zar E Ahmer
这个回答解决了你的问题吗?在Android中编辑文本时只允许数字和字符的验证 - Josh Correia
14个回答

144

在XML中添加以下内容:

 android:digits="abcdefghijklmnopqrstuvwxyz1234567890 "

7
在这种情况下,如果我输入其他任何字符,它会自动输入多个字符。 - hitesh141
有没有办法限制用户只能输入字母或单个空格? - Ravi Bhandari
1
@Ravi 只需要删除数字吗?在末尾保留单个空格。 - user2968401
1
这不允许大写字符,而 OP 要求的是大写字符。 - Steven Byle
6
这个解决方案再加上 textAllCaps="true" 应该就可以实现这个目的。 - Mino
显示剩余5条评论

36
如何限制EditText仅接受字母数字字符,以便无论用户键入哪个小写或大写键,EditText都将显示大写
解决方案是使用InputFilter,它可以让您在比android:digits更细的粒度级别上完全控制筛选输入。如果所有字符都有效,则filter()方法应返回null;如果某些字符无效,则应返回只包含有效字符的CharSequence。如果复制并粘贴了多个字符,并且其中一些字符无效,则只保留有效字符。
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();
    }
}

此外,在设置InputFilter时,您必须确保不覆盖在EditText上设置的其他InputFilters;这些可能是在XML中设置的,例如android:maxLength。您还必须考虑设置InputFilters的顺序,它们会按照设置的顺序应用。幸运的是,InputFilter.AllCaps已经存在,因此将其应用于我们的字母数字过滤器将保留所有字母数字文本,并将其转换为大写。

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

2
这应该是被接受的答案。我已经尝试了这个和其他页面上提供的解决方案,只有这个解决方案完美地覆盖了我所有的设备(三星是一个特别讨厌的设备)。有些只给了我数字输入,有些则在输入时抱怨初始长度为0个字符。我还会将设置过滤器简写为editText.setFilters(new InputFilter[]{new InputFilter.AllCaps(), alphanumericFilter}); - ZooS
没起作用。当用户输入一个非有效字符时,编辑文本上的当前文本会加倍!! - Felipe Ribeiro R. Magalhaes
1
当您连续输入两个数字时,会出现错误。 - Felipe Ribeiro R. Magalhaes
我需要限制谷歌印地语键盘中的数学符号“π”。我该如何使用这种方法实现? - Roohi Zuwairiyah
1
如果您有多个非互斥的过滤器,例如长度为10的过滤器和字母数字过滤器,则应先应用字母数字过滤器,然后再应用长度为10的过滤器。否则,如果先应用长度过滤器,则会将其修剪为10,然后在应用字母数字过滤器时可能会删除更多的非字母数字字符,错误地仅将字母数字过滤器应用于前10个字符(而不是保留最多10个字母数字字符)。当用户从密码管理器等处粘贴文本到EditText中时,这将发挥作用。 - Steven Byle
显示剩余8条评论

20

如果您不需要太多自定义,一个简单的技巧是从上面的例子中找到您想要添加的所有字符并将其添加到android:digits中。

android:digits="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"

这应该可以接受大小写字母数字值。


2
这对于多语言应用程序将会失败。 - MobileEvangelist

13

使用此代码:

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

我尝试按照此问题的已接受答案评论中建议的方法使用textAllCaps="true",但它并没有像预期的那样工作。


1
这对于多语言应用程序会失败。 - MobileEvangelist

8
您不需要编写任何正则表达式,只需将XML属性添加到EditText即可。
android:digits="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
android:inputType="textCapCharacters"

已测试完美地用于PAN卡验证。


1
时间节省器!非常感谢。 - Karan Thakkar
1
不正常工作。输入无效(特殊)字符时会出现故障。 - Salman Khalid

6

试试这个:

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

6

极简主义 Kotlin 实现:

fun EditText.allowOnlyAlphaNumericCharacters() {
    filters = filters.plus(
        listOf(
            InputFilter { s, _, _, _, _, _->
                s.replace(Regex("[^A-Za-z0-9]"), "")
            },
            InputFilter.AllCaps()
        )
    )
}

这导致了一个奇怪的错误,输入后,EditText 填充了无法删除的随机字母。 - Aba
请尝试使用以下链接:https://dev59.com/Y2Ag5IYBdhLWcg3wwtRp#68709480。以上是更新版本。 - Idris Bohra

2
<EditText
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="PromoCode"
                    android:digits="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789,_,-"
                    android:inputType="text" />

2

我尝试了@methodSignature的解决方案,但正如@Aba所提到的那样,它会生成重复/奇怪的字符串。因此进行了修改。

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

2

为此,您需要创建自定义过滤器并将其设置为EditText,如下所示。

这将自动将您的字母转换为大写字母。

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

没有需要在xml文件中设置的额外参数。

我已经使用这种方法根据某些条件将最后一个字符变为大写。谢谢。 - Gunavant Patel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接