Cómo actualizar el mismo EditText con TextWatcher?

En mi aplicación Android necesito implementar una interfaz TextWatcher para implementar onTextChanged . El problema que tengo es, quiero actualizar el mismo EditText con una cadena extra. Cuando intento hacer esto el programa termina.

  final EditText ET = (EditText) findViewById(R.id.editText1); ET.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { try { ET.setText("***"+ s.toString()); ET.setSelection(s.length()); } catch(Exception e) { Log.v("State", e.getMessage()); } } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void afterTextChanged(Editable s) { } }); 

Mi programa termina e incluso trato de capturar la excepción como en mi código aún termina. ¿Alguien tiene alguna idea de por qué sucede esto y cómo puedo lograr esto? Gracias.

El contenido de TextView se puede editar en el evento onTextChanged .

En su lugar, debe manejar el evento afterTextChanged para poder realizar cambios en el texto.

Para una explicación más detallada, vea: Android TextWatcher.afterTextChanged vs TextWatcher.onTextChanged


Nota : Error onTextChanged

Obvioulsy, estás causando un bucle sin fin cambiando continuamente el texto en el evento afterTextChanged .

Desde la ref :

Público abstract void afterTextChanged (Editable s)
Este método se llama para notificarle que, en algún lugar dentro de s, el texto ha sido cambiado. Es legítimo realizar cambios adicionales en s desde esta devolución de llamada, pero tenga cuidado de no meterse en un bucle infinito, ya que cualquier cambio que realice hará que este método se vuelva a llamar de forma recursiva.

  • Sugerencia 1 : si puede, compruebe si el s ya es lo que quiere cuando se desencadena el evento.

     @Override public void afterTextChanged(Editable s) { if( !s.equalsIngoreCase("smth defined previously")) s = "smth defined previously"; } 
  • Sugerencia 2 : si necesitas hacer cosas más complejas (formato, validación) tal vez puedas usar un método synchronized como en este post.

Nota 2 : Formatear la entrada como parcialmente oculta con n estrellas hasta los últimos 4 caracteres (**** cuatro)

Puedes usar algo como esto en la sugerencia 1 :

  @Override public void afterTextChanged(Editable s) { String sText = ET.getText().toString() if( !isFormatted(sText)) s = format(sText); } bool isFormatted(String s) { //check if s is already formatted } string format(String s) { //format s & return } 

Para complementar la respuesta de Zortkun (donde el código de ejemplo es bastante roto), esto es cómo usar afterTextChanged() para actualizar el mismo EditText :

 editText.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void afterTextChanged(Editable editable) { if (!editable.toString().startsWith("***")) { editable.insert(0, "***"); } } }); 

Familiarícese con la interfaz Editable para aprender sobre otras operaciones además de insert() .

Tenga en cuenta que es fácil terminar en un bucle infinito (los cambios que provocan afterTextChanged() nuevo), por lo que típicamente haría sus cambios dentro de una condición if , como se ha indicado anteriormente.

Como afterTextChanged() javadocs decir:

Es legítimo realizar cambios adicionales en s desde esta devolución de llamada, pero tenga cuidado de no meterse en un bucle infinito, ya que cualquier cambio que realice hará que este método se vuelva a llamar de forma recursiva.

Respuesta tardía, si alguien que mira esto es cómo lo hice.

  • Set addTextChangedListener inicialmente
  • En una de las llamadas de retorno (digamos onTextChanged ()) remove addTextChangedListener
  • Todavía está interesado en recibir actualizaciones agregarlo de nuevo.

Aquí está el código.

 editText.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { Log.d("log", "before"); } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { Log.d("log", "after"); editText.removeTextChangedListener(this); ediText.setText("text you wanted to put"); editText.addTextChangedListener(this); } @Override public void afterTextChanged(Editable s) { } }); 
  • Android - Hacer algo * después de * texto se cambia en EditText
  • Android utiliza el observador de texto para evitar escribir caracteres especiales
  • ¿Cómo eliminar inmediatamente el espacio de un edittext si un usuario presiona el espacio?
  • Android: evalúa EditText después de que el usuario termine de editar
  • Implementación de Text Watcher para EditText
  • No se puede insertar en Editable
  • ¿Cómo puedo hacer algo, 0.5 segundo después de que el texto cambió en mi EditText?
  • TextWatcher para más de un EditText
  • Cómo hacer TextWatcher esperar un tiempo antes de hacer algo de acción
  • Android Manejo de muchos campos de EditText en un ListView
  • Cambiar el color del texto cuando el usuario marca las etiquetas hash
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.