2012-10-09 15 views
18

de Android ¿Cómo puedo evitar que una línea de código como:¿Cómo puedo evitar la ejecución de OnTextChanged en EditarTexto

((EditText) findViewById(R.id.MyEditText)).setText("Hello"); 

causará un evento aquí:

((EditText) findViewById(R.id.MyEditText)).addTextChangedListener(new TextWatcher() { 
@Override 
public void onTextChanged(CharSequence s, int start, 
    int before, int count) { 
// HERE 
} 

@Override 
public void beforeTextChanged(CharSequence s, int start, 
    int count, int after) { 
} 

@Override 
public void afterTextChanged(Editable s) { 
} 
}); 

Quiero saber si hay cualquier forma de inhibir la ejecución de onTextChanged como noté en el caso de seleccionar un resultado desplegable de AutoCompleteTextView (¡no se ejecuta onTextChanged!).

No estoy en busca de soluciones como "hola, si no hacer nada" ...

+11

Configurar el texto activará ese oyente. Una forma simple es hacer una referencia al 'TextWatcher', eliminar el oyente antes de configurar el texto (con' removeTextChangedListener (watcher) '), establecer el texto, re habilitar el oyente (con' addTextChangedListener (watcher) '). Puede tener esto en un método por conveniencia si lo hace más de unas pocas veces. – Luksprog

+0

posible duplicado de [Android: ¿Cómo puedo cambiar el texto de EditText sin activar el Text Watcher que tengo en él?] (Http://stackoverflow.com/questions/9385081/android-how-can-i-change-the- edittext-text-without-triggering-the-text-watcher) – danpetruk

+0

Ejemplo de la misma pregunta resuelta para la actualización en la casilla de verificación con el oyente http://stackoverflow.com/a/15523518/2162226 – gnB

Respuesta

22

La Fuente de los AutoCompleteTextView muestra que establecen un valor lógico decir el texto está siendo sustituida por la realización de bloque

  mBlockCompletion = true; 
     replaceText(convertSelectionToString(selectedItem)); 
     mBlockCompletion = false;  

Esta es una manera tan buena como cualquier otra para lograr lo que quiere hacer. El TextWatcher comprueba entonces para ver si el setText ha llegado a través de una terminación y vuelve fuera del método

void doBeforeTextChanged() { 
    if (mBlockCompletion) return; 

Adición y eliminación de la TextWatcher será más tiempo para la aplicación

1

No creo que hay una manera fácil de desactivar el oyente, pero se puede conseguir alrededor de él, ya sea:

  • Extracción de TextWatcher antes de establecer el texto y volver a agregarlo.
  • O establezca un indicador boolean antes de establecer el texto, que le dice al TextWatcher que lo ignore.

E.g.

boolean ignoreNextTextChange = true; 
((EditText) findViewById(R.id.MyEditText)).setText("Hello"); 

Y en su TextWatcher:

new TextWatcher() { 
    @Override 
    public void onTextChanged(CharSequence s, int start, int before, int count) { 
     /* 
     If the flag is set to ignore the next text change, 
     reset the flag, and return without doing anything. 
     */ 
     if (ignoreNextTextChange){ 
      ignoreNextTextChange = false; 
      return; 
     } 
    } 

    @Override 
    public void beforeTextChanged(CharSequence s, int start, int count, int after) { 

    } 

    @Override 
    public void afterTextChanged(Editable s) { 

    } 
}); 

Es un poco hacky, pero debería funcionar :)

+0

Volviendo allí evitar la ejecución de antes y después del texto cambiado también, o necesitaría otro cheque booleano allí? – Menasheh

0

Sólo dos maneras puedo ver

  • comprobar dentro de la listener
  • agrega/elimina el oyente de acuerdo con cer tain conditions

Como la primera es una solución no deseada para ti, me da miedo que hayas tenido problemas con la segunda.

1

Una forma alternativa de lograr esto sería usar setOnKeyListener.

Esto solo se activará cuando el usuario presione una tecla en lugar de cuando el usuario modifique EditText O mediante programación.

myEditText.setOnKeyListener(new EditText.OnKeyListener() { 
    public boolean onKey(View v, int keyCode, KeyEvent event) { 
     switch(event.getAction()) { 
      case KeyEvent.ACTION_DOWN: 
       // beforeTextChanged 
       break;  
      case KeyEvent.ACTION_UP: 
       // afterTextChanged 
       break; 
     } 
     return false; 
    } 
}); 
5

He tropezado con el mismo problema. Me di cuenta de que ver qué visión tiene actualmente el foco para distinguir entre los eventos activados por el usuario y el programa.

EditText myEditText = ((EditText) findViewById(R.id.myEditText)); 

myEditText.addTextChangedListener(new TextWatcher() 
{ 
    @Override 
    public void onTextChanged(CharSequence s, int start, int before, int count) 
    { 
     if(getCurrentFocus() == myEditText) 
     { 
      // is only executed if the EditText was directly changed by the user 
     } 
    } 

    //... 
}); 
0

Alternativamente puede simplemente usar mEditText.hasFocus() distinguir entre texto que-humano modificado o cambiado por programa, esto funciona muy bien para mí:

@Override 
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) { 
    if (mEditText.hasFocus()) { 
     // Do whatever 
    } 
} 

Espero que esto ayude!

Cuestiones relacionadas