¿Cómo uso InputFilter para limitar caracteres en EditText en Android?

Quiero restringir los caracteres a 0-9, az, AZ y barra espaciadora solamente. Configuración de tipo de entrada Puedo limitar los dígitos, pero no puedo entender las formas en que Inputfilter examina los documentos.

Encontré esto en otro foro. Funciona como un campeón.

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

Los InputFilters son un poco complicados en las versiones de Android que muestran sugerencias de diccionario. A veces obtienes un SpannableStringBuilder, a veces un String simple en el parámetro source .

El siguiente InputFilter debería funcionar. ¡Siéntete libre de mejorar este código!

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

más fácil:

  

Ninguna de las respuestas publicadas funcionó para mí. Vine con mi propia solución:

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

Utilice esto su trabajo 100% su necesidad y muy simple.

  

En strings.xml

 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 

Para evitar caracteres especiales en el tipo de entrada

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

Puede configurar el filtro para su texto de edición como a continuación

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

Además de la respuesta aceptada, también es posible utilizar, por ejemplo: android:inputType="textCapCharacters" como un atributo de para aceptar solo caracteres en mayúscula (y números).

Por alguna razón, el constructor de la clase android.text.LoginFilter tiene un ámbito de paquete, por lo que no puede extenderlo directamente (aunque sería idéntico a este código). Pero puede extender LoginFilter.UsernameFilterGeneric! Entonces solo tienes esto:

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

Esto no está realmente documentado, pero es parte de la biblioteca principal, y la fuente es sencilla . Lo he estado usando desde hace un tiempo, hasta ahora no hay problemas, aunque admito que no he intentado hacer nada complejo que involucre objetos que se puedan abrir.

Correcto, la mejor manera de hacerlo es arreglarlo en el Layout XML utilizando:

  

como correctamente señaló Florian Fröhlich, funciona bien incluso para vistas de texto.

  

Solo una palabra de advertencia, los caracteres mencionados en el android:digits solo se mostrarán, así que ten cuidado de no perder ningún conjunto de caracteres 🙂

Esta solución simple funcionó para mí cuando necesitaba evitar que el usuario ingresara cadenas vacías en EditText. Por supuesto, puedes agregar más personajes:

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

Si subclasifica InputFilter puede crear su propio InputFilter que filtraría cualquier carácter no alfanumérico.

La interfaz InputFilter tiene un método, filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) , y le proporciona toda la información que necesita saber sobre qué caracteres se ingresaron en EditText es asignado a.

Una vez que haya creado su propio InputFilter, puede asignarlo a EditText llamando a setFilters (…).

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

Ignorando las cosas que otras personas han tratado, para manejar las sugerencias del diccionario he encontrado que el siguiente código funciona.

La fuente crece a medida que aumenta la sugerencia, por lo que tenemos que ver cuántos personajes espera que reemplacemos antes de devolver algo.

Si no tenemos ningún carácter no válido, devuelva nulo para que se produzca el reemplazo predeterminado.

De lo contrario, necesitamos extraer los caracteres válidos de la subcadena que REALMENTE se va a colocar en 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= adjustStart) stringBuilder.append(sourceChar); } else includesInvalidCharacter = true; } return includesInvalidCharacter ? stringBuilder : null; } }; 

para evitar palabras en edittext. crea una clase que puedas usar en cualquier momento.

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

Es posible usar setOnKeyListener . En este método, podemos personalizar el texto de edittext entrada!

si también desea incluir el espacio en blanco en su entrada, agregue espacio en el código android: digit como se muestra arriba.

Funciona bien incluso en la versión anterior de Android 4.0.

disfrutar 🙂

Este es un hilo antiguo, pero todas las soluciones propuestas tienen problemas (dependiendo del dispositivo / versión de Android / teclado).

ENFOQUE DIFERENTE

Así que eventualmente fui con un enfoque diferente, en lugar de usar la implementación problemática de InputFilter , estoy usando TextWatcher y TextChangedListener de EditText .

CÓDIGO COMPLETO (EJEMPLO)

 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 razón por la que InputFilter no es una buena solución en Android es porque depende de la implementación del teclado. La entrada del teclado se está filtrando antes de que la entrada se pase a EditText . Pero, debido a que algunos teclados tienen implementaciones diferentes para la invocación de InputFilter.filter() , esto es problemático.

Por otro lado, TextWatcher no se preocupa por la implementación del teclado, nos permite crear una solución simple y asegurarse de que funcione en todos los dispositivos.