5

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

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 finaliza e incluso trato de atrapar la excepción como en mi código todavía termina. ¿Alguien tiene alguna idea de por qué sucede esto y cómo puedo lograrlo? Gracias.

+1

'Cuando trato de hacer esto el programa terminates.' que básicamente significa que debe proporcionar el seguimiento de la pila que se puede encontrar en el LogCat. Eso nos ayudaría mucho! – WarrenFaith

Respuesta

8

El contenido de TextView es no editable en el evento onTextChanged.

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

Para una explicación más detallada, véase a fondo: Android TextWatcher.afterTextChanged vs TextWatcher.onTextChanged


Nota: Error onTextChanged

Obvioulsy, que están causando un bucle sin fin, cambiando de forma continua el textoen afterTextChanged evento.

De the ref:

public abstract void afterTextChanged (editable s)
Este método se llama para notificar que, en algún lugar dentro de s, el texto ha sido cambiado . Es legítimo realizar más cambios a s desde esta devolución de llamada , pero tenga cuidado de no introducirse en un bucle infinito, , ya que cualquier cambio que realice ocasionará que este método se vuelva a llamar recursivamente. ...

  • Sugerencia 1: si se puede, y comprueba si el s es ya lo que quiere cuando se activa el evento.

    @Override 
    public void afterTextChanged(Editable s) 
    {  
        if(!s.equalsIngoreCase("smth defined previously")) 
         s = "smth defined previously";    
    } 
    
  • Sugerencia 2: si lo que necesita hacer cosas más complejas (formateo, validación) que tal vez puede utilizar un método synchronized como en this post.

Nota 2: Formateando la entrada como parcialmente oculta con n estrellas hasta la última cha rs (****) de cuatro

Usted puede usar algo como esto en 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 
    } 
+0

HI Zorkun, intenté agregar el mismo código en el evento afterTextChanged (Editable s) ... Todavía termina ... ¿Conoces alguna otra forma alternativa de hacer esto?Gracias – JibW

+0

La s es editable dentro de afterTextChanged (Editable s). Pero aún no puede asignarse a EditText. – JibW

+0

Sí Eso es cierto. Causa un bucle sin fin al cambiar continuamente el texto en el evento afterTextChanged. Lo que pasa es que quiero ocultar las primeras letras en EditText, con Some character as * y dejar que solo los últimos 4 caracteres estén visibles ... – JibW

1

Para complementar Zortkun's answer (donde el código de ejemplo está bastante roto), así es como se había afterTextChanged() utilizar 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, "***"); 
     }   
    } 
}); 

familiarizarse con la interfaz Editable para aprender acerca de otras operaciones además de insert().

Tenga en cuenta que es fácil terminar en un bucle infinito (los cambios que no desencadenan afterTextChanged() de nuevo), por lo que normalmente se haría los cambios dentro de un si la condición, como el anterior.

Como afterTextChanged()javadocs dicen:

Es legítimo hacer más cambios a s de esta devolución de llamada, pero tener cuidado de no conseguirse en un bucle infinito, porque cualquier cambios que realice causar este método para ser llamado de nuevo recursivamente.

0

tarde respuesta, si alguien que mira esto es cómo lo hice.

  • conjunto addTextChangedListener inicialmente
  • en una de la llamada de vuelta (digamos OnTextChanged()) eliminar addTextChangedListener
  • sigue interesada en recibir actualizaciones añaden de nuevo otra vez.

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) { 


     } 
    }); 
0

Aquí hay un fragmento que trabajó para mí

etPhoneNumber.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 s) { 
      if (!s.toString().equals(Utils.getFormattedNumber(s.toString()))) { 
       s.replace(0, s.length(), Utils.getFormattedNumber(s.toString())); 
      } 
     } 
    }); 

donde Utils.getFormattedPhoneNumber() es su método de devolución de un número formateado

Cuestiones relacionadas