¿Cómo puedo hacer algo, 0.5 segundo después de que el texto cambió en mi EditText?

Estoy filtrando mi lista usando un EditText. Quiero filtrar la lista 0.5 segundos después de que el usuario haya terminado de escribir en EditText . Utilicé el evento TextWatcher de TextWatcher para este propósito. Pero este evento aumenta para cada cambio de carácter en EditText.

¿Que debería hacer?

7 Solutions collect form web for “¿Cómo puedo hacer algo, 0.5 segundo después de que el texto cambió en mi EditText?”

 editText.addTextChangedListener( new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } private Timer timer=new Timer(); private final long DELAY = 500; // milliseconds @Override public void afterTextChanged(final Editable s) { timer.cancel(); timer = new Timer(); timer.schedule( new TimerTask() { @Override public void run() { // TODO: do what you need here (refresh list) // you will probably need to use runOnUiThread(Runnable action) for some specific actions } }, DELAY ); } } ); 

El truco está en cancelar y volver a programar Timer cada vez, cuando el texto en EditText consigue cambiado. ¡Buena suerte!

Utilice mejor el manejador con el método postDelayed (). En la implementación de Android, Timer creará un nuevo subproceso cada vez para ejecutar la tarea. Handler sin embargo tiene su propio Looper que se puede conectar a cualquier hilo que deseamos, por lo que no pagaremos un costo adicional para crear hilo.

Ejemplo

  Handler handler = new Handler(Looper.getMainLooper() /*UI thread*/); Runnable workRunnable; @Override public void afterTextChanged(Editable s) { handler.removeCallbacks(workRunnable); workRunnable = () -> doSmth(s.toString()); handler.postDelayed(workRunnable, 500 /*delay*/); } private final void doSmth(String str) { // } 

También puede utilizar la interfaz TextWatcher y crear su clase personalizada que lo implementa para volver a utilizar muchas veces su CustomTextWatcher y también puede pasar vistas o lo que sea necesario para su constructor:

 public abstract class CustomTextWatcherimplements TextWatcher { //Notice abstract class so we leave abstract method textWasChanged() for implementing class to define it private final TextView myTextView; //Remember EditText is a TextView so this works for EditText also public AddressTextWatcher(TextView tView) { //Notice I'm passing a view at the constructor, but you can pass other variables or whatever you need myTextView= tView; } private Timer timer = new Timer(); private final int DELAY = 500; //milliseconds of delay for timer @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(final Editable s) { timer.cancel(); timer = new Timer(); timer.schedule( new TimerTask() { @Override public void run() { textWasChanged(); } }, DELAY ); } public abstract void textWasChanged(); //Notice abstract method to leave implementation to implementing class 

}

Ahora en tu actividad puedes usarlo así:

  myEditText.addTextChangedListener(new CustomTextWatcher(myEditText) { //Notice I'm passing in constructor of CustomTextWatcher myEditText I needed to use @Override public void textWasChanged() { //doSomething(); this is method inside your activity } }); 

¿Cómo determinas que han terminado de escribir? ¿Que el edittext pierde el foco? Luego hay setOnFocusChangedListener .

Respuesta a la última edición en cuestión : Si desea esperar un tiempo específico después del último trazo de tecla, debe iniciar un hilo en la primera pulsación de tecla (use TextWatcher). Registre constantemente la hora de la última pulsación de tecla. Deje que el hilo duerma a la hora de la última pulsación de tecla + 0,5 segundos. Si la marca de tiempo de la última pulsación de tecla no se ha actualizado, haga lo que usted había previsto.

No de la solución anterior funcionó para mí.

Necesitaba una manera para que TextWatcher no se disparara en cada personaje que ingrese dentro de mi vista de búsqueda y muestre algún progreso, lo que significa que necesito acceder al subproceso de UI.

 private final TextWatcher textWatcherSearchListener = new TextWatcher() { final android.os.Handler handler = new android.os.Handler(); Runnable runnable; public void onTextChanged(final CharSequence s, int start, final int before, int count) { handler.removeCallbacks(runnable); } @Override public void afterTextChanged(final Editable s) { //show some progress, because you can access UI here runnable = new Runnable() { @Override public void run() { //do some work with s.toString() } }; handler.postDelayed(runnable, 500); } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {} }; 

Eliminación de Handler en cada onTextChanged (que se llama cuando el usuario introduce un nuevo carácter). AfterTextChanged se llama después de que el texto se ha cambiado dentro del campo de entrada donde podemos iniciar el nuevo Runnable, pero lo cancelará si el usuario escribe más caracteres (Para más información, cuando se llamen estos llamados, vea esto ). Si el usuario no ingresa más caracteres, el intervalo pasará en postDelayed y llamará al trabajo que debe hacer con ese texto.

Este código se ejecutará sólo una vez por intervalo, no para cada entrada de usuario clave. Espero que ayude a alguien en el futuro.

Puede utilizar EditorActionListener para ese propósito.

 editText.setOnEditorActionListener(new TextView.OnEditorActionListener() { @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if (actionId == EditorInfo.IME_ACTION_DONE) { //Do something here return true; } return false; } }); 

Usar temporizador para su caso no es la mejor solución debido a la creación de nuevo objeto cada vez. De acuerdo con la documentación Timer ( http://developer.android.com/reference/java/util/Timer.html ) es mejor utilizar ScheduledThreadPoolExecutor –

"Los temporizadores programan tareas de un solo disparo o recurrentes para su ejecución. Prefieren ScheduledThreadPoolExecutor para el nuevo código."

Aquí hay un mejor enfoque

 Runnable runnabledelayedTask = new Runnable(){ @Override public void run(){ //TODO perform any operation here } }; editText.addTextChangedListener( new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } private final long DELAY = 500; // milliseconds @Override public void afterTextChanged(final Editable s) { ScheduledExecutorService scheduledPool = Executors.newScheduledThreadPool(1); ScheduledFuture sf = scheduledPool.schedule(callabledelayedTask, DELAY, TimeUnit.MILLISECONDS); //you can cancel ScheduledFuture when needed } } ); 
  • Android: evalúa EditText después de que el usuario termine de editar
  • Cómo hacer TextWatcher esperar un tiempo antes de hacer algo de acción
  • ¿Cómo utilizo AsYouTypeFormatter TextWatcher en la aplicación de Android?
  • Cómo limitar el texto en números sólo de 0-59 en Editar texto en Android?
  • Android utiliza el observador de texto para evitar escribir caracteres especiales
  • Cómo dar formato a la entrada de EditText al escribir con separadores de miles (,) en Android?
  • Cómo manejar la tecla Intro usando TextWatcher en Android
  • Implementación de Text Watcher para EditText
  • ¿Cómo usar la clase TextWatcher en Android?
  • Android TextWatcher.afterTextChanged vs TextWatcher.onTextChanged
  • EditText no se actualiza después de que se cambió el texto en TextWatcher
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.