Как использовать InputFilter для ограничения символов в EditText в Android?

Я хочу ограничить символы только 0-9, a-z, A-Z и пробел. Установка типа ввода Я могу ограничить цифры, но я не могу понять, как InputFilter просматривает документы.

Ответ 1

Я нашел это на другом форуме. Работает как чемпион.

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

Ответ 2

InputFilter немного сложнее в версиях Android, которые отображают предложения словаря. Иногда вы получаете SpannableStringBuilder, иногда просто String в параметре source.

Следующее 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();
        }
    }
}

Ответ 3

намного проще:

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

Ответ 4

Ни один из опубликованных ответов не работал у меня. Я пришел со своим решением:

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

Ответ 5

Используйте эту работу на 100% своей потребности и очень просто.

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

В файле strings.xml

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

Ответ 6

Чтобы избежать специальных символов в типе ввода

public static InputFilter filter = new InputFilter() {
    @Override
    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
        String blockCharacterSet = "~#^|$%*[email protected]/()-'\":;,?{}=!$^';,?×÷<>{}€£¥₩%~`¤♡♥_|《》¡¿°•○●□■◇◆♧♣▲▼▶◀↑↓←→☆★▪:-);-):-D:-(:'(:O 1234567890";
        if (source != null && blockCharacterSet.contains(("" + source))) {
            return "";
        }
        return null;
    }
};

Вы можете настроить фильтр на свой текст редактирования, как показано ниже

edtText.setFilters(new InputFilter[] { filter });

Ответ 7

В дополнение к принятому ответу также можно использовать, например: android:inputType="textCapCharacters", как атрибут <EditText>, чтобы принимать только символы верхнего регистра (и числа).

Ответ 8

По какой-то причине конструктор класса 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;
    }
}

Это действительно не документировано, но это часть основного lib, а источник является простым. Я использую его какое-то время, до сих пор никаких проблем, хотя я признаю, что не пробовал делать что-либо сложное с участием spannables.

Ответ 9

Правильно, лучший способ сделать это, чтобы исправить его в самом макете XML, используя:

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

как правильно указал Флориан Фрелих, он хорошо работает и для текстовых просмотров.

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

Просто предостережение, символы, указанные в android:digits, будут отображаться только, поэтому будьте осторожны, чтобы не пропустить ни одного набора символов:)

Ответ 10

Это простое решение работало для меня, когда мне нужно было запретить пользователю вводить пустые строки в 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});

}

Ответ 11

Если вы подклассифицируете InputFilter, вы можете создать свой собственный InputFilter, который будет отфильтровывать любые не-буквенно-цифровые символы.

Интерфейс InputFilter имеет один метод, filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend), и он предоставляет вам всю информацию, необходимую для того, чтобы узнать, какие символы были введены в EditText, которому он назначен.

Как только вы создали свой собственный InputFilter, вы можете назначить его EditText, вызвав setFilters (...).

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

Ответ 12

Игнорируя информацию о пробелах, с которой другие люди справились, чтобы правильно обрабатывать предложения по словарю, я обнаружил, что работает следующий код.

Источник растет по мере того, как предложение растет, поэтому мы должны посмотреть, сколько персонажей он ожидает от нас, прежде чем мы что-нибудь вернем.

Если у нас нет никаких недопустимых символов, верните значение 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;
    } 
}; 

Ответ 13

для предотвращения слов в edittext. создайте класс, который можно использовать в любое время.

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

Ответ 14

Это старый поток, но все решения имеют проблемы (в зависимости от устройства/версии Android/Keyboard).

РАЗЛИЧНЫЙ ПОДХОД

Итак, в конце концов я пошел с другим подходом, вместо использования InputFilter проблематичной реализации, я использую TextWatcher и TextChangedListener для 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
    onTextChanged(CharSequence s, int start, int before, int count) {
        // Do Nothing
    }
});

Причина InputFilter не является хорошим решением в Android, так как это зависит от реализации клавиатуры. Ввод клавиатуры отфильтровывается до того, как вход передается в EditText. Но, поскольку некоторые клавиатуры имеют разные реализации для вызова InputFilter.filter(), это проблематично.

С другой стороны, TextWatcher не заботится о реализации клавиатуры, это позволяет нам создать простое решение и быть уверенным, что оно будет работать на всех устройствах.

Ответ 15

Можно использовать setOnKeyListener. В этом методе мы можем настроить вход edittext!

Ответ 16

если вы хотите включить пробел в свой ввод, а затем добавьте пробел в код android: digit, как показано выше.

Он отлично работает для меня даже в версии выше android 4.0.

наслаждайтесь:)