Comment utiliser InputFilter pour limiter les caractères dans un texte édité sur Android?

je veux restreindre les caractères à 0-9, A-z, A-Z et barre d'espace seulement. Définir inputtype je peux limiter à des chiffres mais je ne peux pas comprendre les moyens de Inputfilter regarder à travers les docs.

158
demandé sur Tim Wayne 2010-07-28 04:49:33

16 réponses

j'ai trouvé ceci sur un autre forum. Fonctionne comme un champion.

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
répondu moonlightcheese 2014-11-03 10:48:27

InputFilters sont un peu compliqué dans les versions Android qui affichent des suggestions de dictionnaires. Vous obtenez parfois un SpannableStringBuilder, parfois une chaîne simple dans le paramètre source .

L'entrée suivante devrait fonctionner. N'hésitez pas à améliorer ce 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();
        }
    }
}
126
répondu Łukasz Sromek 2013-11-04 15:18:25

beaucoup plus facile:

<EditText
    android:inputType="text"
    android:digits="0,1,2,3,4,5,6,7,8,9,*,qwertzuiopasdfghjklyxcvbnm" />
101
répondu Florian Fröhlich 2014-08-25 21:30:10

aucune réponse affichée n'a fonctionné pour moi. Je suis venu avec ma propre 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 });
56
répondu Kamil Seweryn 2016-07-22 18:32:40

utilisez ceci son travail 100% votre besoin et très simple.

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

en cordes.xml

<string name="myAlphaNumeric">abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789</string>
22
répondu Mohamed Ibrahim 2014-11-04 13:02:22

pour éviter les caractères spéciaux dans le type d'entrée

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

vous pouvez configurer filter pour modifier le texte comme ci-dessous

edtText.setFilters(new InputFilter[] { filter });
14
répondu Priyank Bhojak 2015-05-21 07:48:30

en plus de la réponse acceptée, il est également possible d'utiliser par exemple: android:inputType="textCapCharacters" comme attribut de <EditText> afin de n'accepter que les caractères majuscules (et les nombres).

7
répondu mblenton 2011-10-14 00:01:43

C'est juste, la meilleure façon de le faire pour le corriger dans la mise en page XML elle-même en utilisant:

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

comme L'a souligné à juste titre Florian Fröhlich, il fonctionne même bien pour les vues de texte.

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

juste un mot de mise en garde, les caractères mentionnés dans le android:digits ne seront affichés, donc faites attention à ne manquer aucun ensemble de caractères:)

6
répondu Kailas 2016-04-15 04:15:00

pour une raison inconnue l'androïde.texte.Le constructeur de la classe LoginFilter a une portée paquet, donc vous ne pouvez pas l'étendre directement (même si elle serait identique à ce code). Mais vous pouvez étendre LoginFilter.UsernameFilterGeneric! Alors vous avez juste ceci:

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

ce n'est pas vraiment documenté, mais cela fait partie du noyau lib, et la source est simple . Je l'utilise depuis un certain temps maintenant, jusqu'à présent pas de problèmes, bien que je l'admette Je n'ai pas essayé de faire quelque chose de complexe impliquant des spannables.

5
répondu Groxx 2013-12-13 21:46:07

Cette solution simple a fonctionné pour moi quand j'avais besoin d'empêcher l'utilisateur de saisir des chaînes vides dans un texte D'édition. Vous pouvez bien sûr ajouter plus de caractères:

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
répondu Swifty McSwifterton 2013-10-19 04:56:06

si vous classez InputFilter, vous pouvez créer votre propre InputFilter qui filtrerait tous les caractères non alphanumériques.

L'Interface InputFilter a une méthode, filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) , et elle vous fournit toutes les informations dont vous avez besoin pour savoir quels caractères ont été entrés dans le texte D'édition qui lui est assigné.

une fois que vous avez créé votre propre InputFilter, vous pouvez l'affecter à L'EditText en appelant setFilters(...).

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

1
répondu nicholas.hauschild 2010-07-28 02:28:35

ignorant le truc de portée que d'autres personnes ont traité, pour bien gérer les suggestions de dictionnaires, j'ai trouvé le code suivant fonctionne.

la source croît au fur et à mesure que la suggestion grandit, nous devons donc regarder combien de caractères elle s'attend en fait à ce que nous remplacions avant que nous ne rendions quoi que ce soit.

si nous n'avons pas de caractères invalides, retournez null pour que le remplacement par défaut se produise.

sinon nous devons extraire les caractères valides du substrat qui va être placé dans le texte D'édition.

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
répondu Christian Whitehouse 2014-08-07 20:50:48

pour empêcher les mots dans edittext. créez une classe que vous pourriez utiliser à tout moment.

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
répondu Sahar Millis 2015-02-02 08:13:25

il est possible d'utiliser setOnKeyListener . Dans cette méthode, nous pouvons personnaliser l'entrée edittext !

0
répondu Võ Hoài Lên 2011-12-12 18:14:26

si vous voulez inclure l'espace blanc dans votre entrée, puis ajouter de l'espace dans android:code à quatre chiffres, comme indiqué ci-dessus.

Il fonctionne très bien pour moi, même dans la version 4.0 d'android.

enjoy:)

0
répondu Ujjwal 2014-05-21 08:29:18

il s'agit d'un vieux fil, mais les solutions proposées ont toutes des problèmes (en fonction de l'appareil / version Android / Clavier).

DIFFERENT APPROACH

donc j'ai finalement opté pour une approche différente, au lieu d'utiliser la mise en œuvre problématique InputFilter , j'utilise TextWatcher et TextChangedListener du EditText .

CODE COMPLET (EXEMPLE)

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

la raison InputFilter n'est pas une bonne solution sur Android est car elle dépend de l'implémentation du clavier. L'entrée clavier est filtrée avant de passer à la EditText . Mais, parce que certains claviers ont des implémentations différentes pour l'invocation InputFilter.filter() , c'est problématique.

d'autre part TextWatcher ne se soucie pas de l'implémentation du clavier, il nous permet de créer un simple solution et assurez-vous qu'elle fonctionne sur tous les appareils.

0
répondu Eyal Biran 2017-12-12 11:12:35