Jak używać InputFilter do ograniczania znaków w edytowanym tekście w systemie Android?

Chcę ograniczyć znaki tylko do 0-9, a - z, A-Z i spacji. UstawiajÄ ... c inputtype moĹźe ograniczyÄ ‡ siÄ ™ do cyfr, ale nie moĹźe rozgryĺşä‡, w jaki sposĂłb Inputfilter przeglÄ ... daÄ ‡ dokumentĂłw.

Author: Tim Wayne, 2010-07-28

16 answers

Znalazłem to na innym forum. Działa jak mistrz.

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 });
 170
Author: moonlightcheese,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-03 10:48:27

Filtry Input są nieco skomplikowane w wersjach Androida, które wyświetlają sugestie słownikowe. Czasami otrzymujesz SpannableStringBuilder, czasami zwykły ciąg znaków w parametrze source.

NastÄ ™ pujÄ ... cy Filtr Input powinien dziaĹ ' ać. Zapraszam do poprawy tego kodu!

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();
        }
    }
}
 126
Author: Łukasz Sromek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-04 15:18:25

O wiele łatwiej:

<EditText
    android:inputType="text"
    android:digits="0,1,2,3,4,5,6,7,8,9,*,qwertzuiopasdfghjklyxcvbnm" />
 101
Author: Florian Fröhlich,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-25 21:30:10

Żadna z zamieszczonych odpowiedzi nie zadziałała dla mnie. Przyszedłem z własnym rozwiązaniem:

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 });
 56
Author: Kamil Seweryn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-22 18:32:40

Użyj tego jego praca 100% swoje potrzeby i bardzo proste.

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

W ciągach.xml

<string name="myAlphaNumeric">abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789</string>
 22
Author: Mohamed Ibrahim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-04 13:02:22

Aby uniknąć znaków specjalnych w typie wejściowym

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

Możesz ustawić filtr do edycji tekstu jak poniżej

edtText.setFilters(new InputFilter[] { filter });
 14
Author: Priyank Bhojak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-21 07:48:30

Oprócz zaakceptowanej odpowiedzi, możliwe jest również użycie np.: android:inputType="textCapCharacters" jako atrybutu <EditText>, aby akceptować tylko wielkie litery (i cyfry).

 7
Author: mblenton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-14 00:01:43

Dobrze, najlepiej to naprawić w samym układzie XML używając:

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

Jak słusznie zauważył Florian Fröhlich, działa dobrze nawet dla widoków tekstu.

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

Tylko słowo ostrożności, znaki wymienione w android:digits będą wyświetlane tylko, więc uważaj, aby nie przegapić żadnego zestawu znaków:)

 6
Author: Kailas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-15 04:15:00

Z jakiegoś powodu android.tekst.Konstruktor klasy LoginFilter jest pakietowo-scopedowy, więc nie można go bezpośrednio rozszerzyć (nawet jeśli byłby identyczny z tym kodem). Ale można rozszerzyć LoginFilter./ Align = "left" / Wtedy masz tylko to:

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

To nie jest tak naprawdę udokumentowane, ale jest częścią podstawowej lib, a źródło jest proste . Używam go już od jakiegoś czasu, do tej pory żadnych problemów, choć przyznaję, że nie próbowałem robić nic skomplikowanego spannables.

 5
Author: Groxx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-13 21:46:07

To proste rozwiązanie działało dla mnie, gdy musiałem uniemożliwić użytkownikowi wprowadzanie pustych łańcuchów do EditText. Można oczywiście dodać więcej znaków:

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

}
 4
Author: Swifty McSwifterton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-19 04:56:06

Jeśli podklasujesz InputFilter, możesz utworzyć swój własny InputFilter, który odfiltrowałby dowolne nie-alfanumeryczne znaki.

Interfejs InputFilter posiada jedną metodę, filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) i dostarcza wszystkich informacji, które musisz wiedzieć o tym, które znaki zostały wprowadzone do EditText, do którego jest przypisany.

Po utworzeniu własnego InputFilter, możesz przypisać go do EditText przez wywołanie setFilters(...).

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

 1
Author: nicholas.hauschild,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-28 02:28:35

Ignorując rzeczy span, z którymi inni ludzie mieli do czynienia, aby poprawnie obsłużyć sugestie słownikowe znalazłem następujący kod działa.

Źródło rośnie wraz z sugestią, więc musimy przyjrzeć się, ile postaci oczekuje od nas wymiany, zanim cokolwiek zwrócimy.

Jeśli nie mamy żadnych nieprawidłowych znaków, zwracamy null tak, że nastąpi domyślne zastąpienie.

W przeciwnym razie musimy wyodrębnić prawidłowe znaki z podłańcucha, który Właściwie zostanie umieszczony w edytorze.

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;
    } 
}; 
 1
Author: Christian Whitehouse,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-07 20:50:48

Aby zapobiec słowom w edittext. stwórz klasę, której możesz użyć w każdej chwili.

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;
    }
}
 1
Author: Sahar Millis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-02 08:13:25

Możliwe jest użycie setOnKeyListener. W tej metodzie możemy dostosować wejście edittext !

 0
Author: Võ Hoài Lên,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-12 18:14:26

Jeśli chcesz również umieścić białą spację w swoim wejściu, dodaj spację w systemie Android:kod cyfrowy, jak pokazano powyżej.

U mnie działa dobrze nawet w wersji powyżej Androida 4.0.

Enjoy:)

 0
Author: Ujjwal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-21 08:29:18

To stary wątek, ale wszystkie rozwiązania mają problemy (w zależności od urządzenia / wersji Androida / klawiatury).

INNE PODEJŚCIE

Więc w końcu wybrałem inne podejście, zamiast używać InputFilter problematycznej implementacji, używam TextWatcher i TextChangedListener z EditText.

PEŁNY KOD (PRZYKŁAD)

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

Powodem InputFilter nie jest dobrym rozwiązaniem w Androidzie, ponieważ zależy to od implementacji klawiatury. Na Wejście klawiatury jest filtrowane przed przekazaniem do EditText. Ponieważ jednak niektóre klawiatury mają różne implementacje wywołania InputFilter.filter(), jest to problematyczne.

Z drugiej strony TextWatcher nie dba o implementację klawiatury, pozwala nam stworzyć proste rozwiązanie i mieć pewność, że będzie działać na wszystkich urządzeniach.

 0
Author: Eyal Biran,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-12 11:12:35