Je veux restreindre les caractères à 0-9, a-z, A-Z et barre d'espace uniquement. La définition du type d’entrée que je peux limiter aux chiffres est impossible, mais je ne peux pas comprendre la façon dont Inputfilter examine les documents.
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 });
Les InputFilter
s sont un peu compliqués dans les versions de Android qui affichent des suggestions de dictionnaires. Vous obtenez parfois un SpannableStringBuilder
, parfois un simple String
dans le paramètre source
.
Le InputFilter
suivant 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();
}
}
}
beaucoup plus facile:
<EditText
Android:inputType="text"
Android:digits="0,1,2,3,4,5,6,7,8,9,*,qwertzuiopasdfghjklyxcvbnm" />
Aucune des réponses postées 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 });
Utilisez ceci son travail 100% votre besoin et très simple.
<EditText
Android:inputType="textFilter"
Android:digits="@string/myAlphaNumeric" />
Dans strings.xml
<string name="myAlphaNumeric">abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789</string>
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 définir le filtre à votre texte d'édition comme ci-dessous
edtText.setFilters(new InputFilter[] { filter });
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).
C’est bien, le meilleur moyen de 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, cela fonctionne bien pour les vues de texte même.
<TextView
Android:inputType="text"
Android:digits="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" />
Juste un mot d'avertissement, les caractères mentionnés dans le Android:digits
ne seront affichés que, alors veillez à ne rater aucun jeu de caractères :)
Pour une raison quelconque, le constructeur de la classe Android.text.LoginFilter est défini sur le paquet, de sorte que vous ne pouvez pas l'étendre directement (même s'il serait identique à ce code). Mais vous pouvez étendre LoginFilter.UsernameFilterGeneric! Ensuite, 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 de la bibliothèque principale, et la source est simple . Je l'utilise depuis un moment, jusqu'à présent, pas de problème, bien que j'avoue que je n'ai jamais essayé de faire quelque chose de complexe impliquant des spannables.
Cette solution simple fonctionnait pour moi lorsque je devais empêcher l'utilisateur de saisir des chaînes vides dans un EditText. 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});
}
C'est un vieux fil de discussion, mais les solutions proposées ont toutes des problèmes (en fonction du périphérique/Android version/du clavier).
APPROCHE DIFFÉRENTE
Alors finalement, j’ai opté pour une approche différente, au lieu d’utiliser l’implémentation problématique de InputFilter
, j’utilise TextWatcher
et le TextChangedListener
de 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 pour laquelle InputFilter
n’est pas une bonne solution dans Android est qu’elle dépend de l’implémentation du clavier. L'entrée du clavier est filtrée avant que l'entrée ne soit transmise à la variable EditText
. Mais comme certains claviers ont des implémentations différentes pour l'invocation InputFilter.filter()
, cela pose problème.
D'autre part, TextWatcher
ne se soucie pas de l'implémentation du clavier, cela nous permet de créer une solution simple et de nous assurer que cela fonctionnera sur tous les périphériques.
En ignorant les éléments de span que d'autres personnes ont traités, pour gérer correctement les suggestions de dictionnaire, j'ai trouvé que le code suivant fonctionnait.
La source augmente au fur et à mesure que la suggestion augmente, nous devons donc déterminer le nombre de caractères que nous attendons réellement de notre part avant de renvoyer quoi que ce soit.
Si nous n'avons pas de caractères non valides, retourne null pour que le remplacement par défaut se produise.
Sinon, nous devons extraire les caractères valides de la sous-chaîne qui sera ACTUELLEMENT placée dans le 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;
}
};
empêcher les mots dans edittext. créer 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;
}
}
Si vous sous-classez InputFilter, vous pouvez créer votre propre InputFilter qui filtrera 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 nécessaires sur les caractères entrés dans le texte d’édition lui étant attribué.
Une fois que vous avez créé votre propre InputFilter, vous pouvez l'affecter à EditText en appelant setFilters (...).
http://developer.Android.com/reference/Android/text/InputFilter.html#filter (Java.lang.CharSequence , int, int, Android.text.Spanned, int, int)
si vous souhaitez également inclure un espace dans votre entrée, ajoutez un espace dans Android: code du chiffre comme indiqué ci-dessus.
Cela fonctionne bien pour moi, même dans la version ci-dessus Android 4.0.
prendre plaisir :)
Il est possible d'utiliser setOnKeyListener
. Dans cette méthode, nous pouvons personnaliser l'entrée edittext
!