如何使用 InputFilter 来限制 Android 中 EditText 中的字符?

发布于 2024-09-12 02:14:40 字数 66 浏览 6 评论 0原文

我想将字符限制为 0-9、az、AZ 和空格键。设置输入类型我可以限制为数字,但我无法弄清楚输入过滤器浏览文档的方式。

I want to restrict the chars to 0-9, a-z, A-Z and spacebar only. Setting inputtype I can limit to digits but I cannot figure out the ways of Inputfilter looking through the docs.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(20

何其悲哀 2024-09-19 02:14:41

您可以在正则表达式中指定所需的字符并在 InputFilter 中使用它:

val regex = Regex("[a-zA-Z\\d ]")
    
editText.filters = arrayOf(InputFilter { source, _, _, _, _, _ ->
    source.filter { regex.matches(it.toString()) }
})

注意,我没有使用 \w 字符类,因为它包含下划线 _

You can specify wanted characters in a regex and use it in InputFilter:

val regex = Regex("[a-zA-Z\\d ]")
    
editText.filters = arrayOf(InputFilter { source, _, _, _, _, _ ->
    source.filter { regex.matches(it.toString()) }
})

Notice, I didn't use \w character class, because it includes underscore _

稍尽春風 2024-09-19 02:14:41

由于某种原因, 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;
    }
}

这并没有真正记录下来,但它是核心库的一部分,并且 源代码很简单。我已经使用它有一段时间了,到目前为止没有任何问题,尽管我承认我还没有尝试过做任何涉及跨度的复杂事情。

For some reason the android.text.LoginFilter class's constructor is package-scoped, so you can't directly extend it (even though it would be identical to this code). But you can extend LoginFilter.UsernameFilterGeneric! Then you just have this:

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

This isn't really documented, but it's part of the core lib, and the source is straightforward. I've been using it for a while now, so far no problems, though I admit I haven't tried doing anything complex involving spannables.

南街九尾狐 2024-09-19 02:14:41

当我需要阻止用户在 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});

}

This simple solution worked for me when I needed to prevent the user from entering empty strings into an EditText. You can of course add more characters:

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

}
无悔心 2024-09-19 02:14:41

这是一个旧线程,但专用解决方案都有问题(取决于设备/Android 版本/键盘)。

不同的方法

所以最终我采用了不同的方法,而不是使用 InputFilter 有问题的实现,我使用 TextWatcherTextChangedListener 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 不关心键盘实现,它允许我们创建一个简单的解决方案并确保它适用于所有设备。

This is an old thread, but the purposed solutions all have issues (depending on device / Android version / Keyboard).

DIFFERENT APPROACH

So eventually I went with a different approach, instead of using the InputFilter problematic implementation, I am using TextWatcher and the TextChangedListener of the EditText.

FULL CODE (EXAMPLE)

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

The reason InputFilter is not a good solution in Android is since it depends on the keyboard implementation. The Keyboard input is being filtered before the input is passed to the EditText. But, because some keyboards have different implementations for the InputFilter.filter() invocation, this is problematic.

On the other hand TextWatcher does not care about the keyboard implementation, it allows us to create a simple solution and be sure it will work on all devices.

む无字情书 2024-09-19 02:14:41

如果您对 InputFilter 进行子类化,则可以创建自己的 InputFilter 来过滤掉任何非字母数字字符。

InputFilter 接口有一个方法,filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend),它为您提供有关哪些字符所需的所有信息被输入到它分配给的 EditText 中。

创建自己的 InputFilter 后,可以通过调用 setFilters(...) 将其分配给 EditText。

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

If you subclass InputFilter you can create your own InputFilter that would filter out any non-alpha-numeric characters.

The InputFilter Interface has one method, filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend), and it provides you with all the information you need to know about which characters were entered into the EditText it is assigned to.

Once you have created your own InputFilter, you can assign it to the EditText by calling setFilters(...).

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

别想她 2024-09-19 02:14:41

忽略其他人处理过的跨度内容,为了正确处理字典建议,我发现以下代码有效。

源随着建议的增长而增长,因此我们必须在返回任何内容之前查看它实际上期望我们替换多少个字符。

如果没有任何无效字符,则返回 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;
    } 
}; 

Ignoring the span stuff that other people have dealt with, to properly handle dictionary suggestions I found the following code works.

The source grows as the suggestion grows so we have to look at how many characters it's actually expecting us to replace before we return anything.

If we don't have any invalid characters, return null so that the default replacement occurs.

Otherwise we need to extract out the valid characters from the substring that's ACTUALLY going to be placed into the 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;
    } 
}; 
无言温柔 2024-09-19 02:14:41

以防止编辑文本中出现单词。
创建一个你可以随时使用的类。

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

to prevent words in edittext.
create a class that u could use anytime.

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;
    }
}
苦行僧 2024-09-19 02:14:41

可以使用setOnKeyListener。在这个方法中,我们可以自定义输入 edittext

It is possible to use setOnKeyListener. In this method, we can customize the input edittext !

甜妞爱困 2024-09-19 02:14:41

这就是我在编辑文本中为名称字段创建过滤器的方法。(第一个字母是大写字母,每个单词后只允许有一个空格。

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

This is how I created filter for the Name field in Edit Text.(First letter is CAPS, and allow only single space after every word.

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)});
}
弄潮 2024-09-19 02:14:41

我在 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
        }
    }
}

并使用扩展函数获取类:

fun EditText.filterByDataType(filterType: Int) {
    this.filters = arrayOf<InputFilter>(InputFilterAlphanumeric(filterType))
}

I have the same answer in 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
        }
    }
}

and get the class with an Extension function:

fun EditText.filterByDataType(filterType: Int) {
    this.filters = arrayOf<InputFilter>(InputFilterAlphanumeric(filterType))
}
暖心男生 2024-09-19 02:14:40

我在另一个论坛上找到了这个。像冠军一样工作。

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

I found this on another forum. Works like a champ.

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 });
樱花细雨 2024-09-19 02:14:40

在显示字典建议的 Android 版本中,InputFilter 有点复杂。有时您会在 source 参数中得到一个 SpannableStringBuilder,有时会得到一个普通的 String

以下 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();
        }
    }
}

InputFilters are a little complicated in Android versions that display dictionary suggestions. You sometimes get a SpannableStringBuilder, sometimes a plain String in the source parameter.

The following InputFilter should work. Feel free to improve this code!

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();
        }
    }
}
一江春梦 2024-09-19 02:14:40

更容易:

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

much easier:

<EditText
    android:inputType="text"
    android:digits="0,1,2,3,4,5,6,7,8,9,*,qwertzuiopasdfghjklyxcvbnm" />
阳光的暖冬 2024-09-19 02:14:40

发布的答案都不适合我。我有自己的解决方案:

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

None of posted answers did work for me. I came with my own solution:

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 });
晨曦慕雪 2024-09-19 02:14:40

使用它可以 100% 满足您的需要,而且非常简单。

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

在 strings.xml 中

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

Use this its work 100% your need and very simple.

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

In strings.xml

<string name="myAlphaNumeric">abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789</string>
慈悲佛祖 2024-09-19 02:14:40

为了简单起见,我做了这样的事情:

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 编写的。

I have done something like this to keep it simple:

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

This way we are replacing all the unwanted characters in the new part of the source string with an empty string.

The edit_text variable is the EditText object we are referring to.

The code is written in kotlin.

安静 2024-09-19 02:14:40

为了避免输入类型中出现特殊字符,

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

To avoid Special Characters in input type

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

You can set filter to your edit text like below

edtText.setFilters(new InputFilter[] { filter });
他是夢罘是命 2024-09-19 02:14:40

首先添加到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))

我通常还设置 maxLengthfiltersinputType

First add into strings.xml:

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

XML:

android:digits="@string/vin_code_mask"

Code in 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
}

Strange, but it works weirdly on emulator's soft keyboard.

Warning! The following code will filter all letters and other symbols except digits for software keyboards. Only digital keyboard will appear on smartphones.

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

I also usually set maxLength, filters, inputType.

除了接受的答案之外,还可以使用例如: android:inputType="textCapCharacters" 作为 的属性,以便仅接受上限大小写字符(和数字)。

In addition to the accepted answer, it is also possible to use e.g.: android:inputType="textCapCharacters" as an attribute of <EditText> in order to only accept upper case characters (and numbers).

嘴硬脾气大 2024-09-19 02:14:40

是的,最好的方法是在 XML 布局本身中修复它:

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

正如 Florian Fröhlich 正确指出的那样,它甚至适用于文本视图。

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

请注意,仅显示 android:digits 中提到的字符,因此请小心不要错过任何字符集:)

It's Right, the best way to go about it to fix it in the XML Layout itself using:

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

as rightly pointed by Florian Fröhlich, it works well for text views even.

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

Just a word of caution, the characters mentioned in the android:digits will only be displayed, so just be careful not to miss any set of characters out :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文