How do I use InputFilter to limit characters in an EditText in Android?

后端 未结 20 1125
慢半拍i
慢半拍i 2020-11-22 04:23

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

相关标签:
20条回答
  • 2020-11-22 04:51

    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 });
    
    0 讨论(0)
  • 2020-11-22 04:52

    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;
        } 
    }; 
    
    0 讨论(0)
  • 2020-11-22 04:53

    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).

    0 讨论(0)
  • 2020-11-22 04:55

    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>
    
    0 讨论(0)
  • 2020-11-22 04:57

    much easier:

    <EditText
        android:inputType="text"
        android:digits="0,1,2,3,4,5,6,7,8,9,*,qwertzuiopasdfghjklyxcvbnm" />
    
    0 讨论(0)
  • 2020-11-22 04:58

    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.

    0 讨论(0)
提交回复
热议问题