En Android, los Flows de Kotlin son una manera de representar secuencias de datos asincrónicas que emiten valores de forma continua.
Estos Flows pueden ser útiles en situaciones en las que deseamos escuchar eventos y procesar los resultados de forma asíncrona, como en el caso de una búsqueda en tiempo real.
Implementar búsqueda al escribir sobre un EditText
Para implementar una búsqueda en tiempo real en Android que escuche los eventos de un EditText
y evite que se produzcan muchas consultas de búsqueda en un corto período de tiempo, podemos utilizar la función debounce
de Kotlin.
Esta función nos permite filtrar eventos que lleguen demasiado rápido uno detrás de otro, permitiéndonos especificar un tiempo mínimo que debe transcurrir entre eventos para que sean emitidos al Flow
.
Para utilizar el debounce con los Flows de Kotlin, podemos seguir los siguientes pasos:
Creamos una función de extensión para escuchar los cambios
Creamos una función de extensión sobre la clase EditText
que devuelva un Flow
con los cambios de texto del EditText
.
Podemos hacer esto utilizando el método callbackFlow
de Kotlin, que nos permite crear un Flow
que se alimenta de callbacks.
fun EditText.textChanges(): Flow<CharSequence> { return callbackFlow { val textWatcher = object : TextWatcher { override fun afterTextChanged(s: Editable?) = Unit override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) = Unit override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { // este método se llama cuando el texto está cambiando trySend(s) // emitimos el valor al Flow } } addTextChangedListener(textWatcher) awaitClose { removeTextChangedListener(textWatcher) } } }
Emitir valores solo si ha pasado cierto tiempo
Ahora podemos utilizar la función de extensión que hemos creado para obtener un Flow
con los cambios de texto del EditText
.
A continuación, aplicamos la función debounce
al Flow
para especificar un tiempo mínimo que debe transcurrir entre eventos para que sean emitidos.
val editText = EditText(context) editText.textChanges() .debounce(500) // espere 500ms sin eventos para emitir el valor .onEach { text -> println("Texto actual: $text") } .launchIn(uiScope)
Con esto, cada vez que el usuario cambie el texto del EditText
, se emitirá un evento al Flow
.
Sin embargo, si el usuario escribe rápidamente y produce varios cambios de texto en menos de 500ms, solo se emitirá el último evento después de que hayan pasado 500ms sin nuevos cambios de texto.
Por último, podemos utilizar el Flow
para realizar una búsqueda en tiempo real utilizando una API de búsqueda o cualquier otra lógica de procesamiento que necesitemos. Por ejemplo:
val editText = EditText(context) editText.textChanges() .debounce(500) // espere 500ms sin eventos para emitir el valor .map { text -> text.toString() } // convertimos el CharSequence a String .filter { text -> text.isNotEmpty() } // filtramos los valores vacíos .distinctUntilChanged() // evitamos hacer búsquedas repetidas .flatMapLatest { query -> searchApi.search(query) // hacemos la búsqueda utilizando la API de búsqueda .asFlow() // convertimos el resultado a un Flow } .onEach { result -> println("Resultado de la búsqueda: $result") } .launchIn(uiScope)
Con esto, cada vez que el usuario escriba en el EditText
y hayan pasado 500ms sin nuevos cambios de texto, se realizará una búsqueda utilizando la API de búsqueda y se mostrará el resultado en la consola.
Conclusión
En conclusión, los Flows de Kotlin son una herramienta útil para representar secuencias de datos asincrónicas en Android y pueden ser utilizados para implementar funcionalidades como la búsqueda en tiempo real.
Al utilizar la función debounce
, podemos filtrar eventos que lleguen demasiado rápido uno detrás de otro y especificar un tiempo mínimo que debe transcurrir entre eventos para que sean emitidos al Flow
.
De esta manera, podemos evitar que se produzcan muchas consultas de búsqueda en un corto período de tiempo y mejorar el rendimiento de nuestra aplicación.
0 comentarios