Un flujo es un tipo de corrutina que puede emitir múltiples valores secuencialmente, a diferencia de las funciones de suspensión, que solo devuelven un único valor. Un flujo, por ejemplo, se puede utilizar para recibir actualizaciones en tiempo real desde una base de datos. Los flujos se construyen sobre corrutinas y pueden devolver múltiples valores. Un flujo es un flujo de datos que se puede calcular de forma asíncrona. Todas las salidas del flujo deben ser del mismo tipo. Un FlowInt, por ejemplo, es un flujo que emite valores enteros. Un flujo es similar a un iterador en el sentido de que produce una secuencia de valores, pero produce y consume valores de forma asincrónica mediante el uso de funciones de suspensión. Esto significa que el flujo, por ejemplo, puede realizar de forma segura una solicitud de red para generar el siguiente valor sin bloquear el hilo principal.
Las siguientes funciones de Kotlin Flow se utilizarán para implementar esta función de búsqueda:
- StateFlow: Ya hemos escrito un artículo al respecto. Puede obtener más información al respecto aquí.
- Operador de un rebote
- Operador de un filtro
- Operador distinto hasta que se cambie
- Último operador FlatMap
Anteriormente, implementar esta función de búsqueda instantánea en Android era difícil con Kotlin Coroutines, pero con Kotlin Flow Operators, se ha vuelto simple e interesante.
Empecemos
En primer lugar, escribiremos una función de extensión que devuelva el StateFlow para que podamos aplicarle los operadores necesarios. Entonces, en SearchView, usaremos setOnQueryTextListener para observar los cambios en el texto, cambiar el estado de la consulta y finalmente devolver el StateFlow como se muestra a continuación:
Kotlin
fun GfGSearch.getQueryTextChangeStateFlow(): StateFlow<String> { val serachQuery = MutableStateFlow("Geeks") setOnQueryTextListener(object : SearchView.OnQueryTextListener { override fun onSearchSubmit(query: String?): Boolean { return true } override fun onTermChange(newText: String): Boolean { serachQuery.value = newText return true } }) return serachQuery }
Luego, para probar esto, tomamos algún intercambio de pseudo red para los datos.
Kotlin
// Fake network transaction private fun someDataFetch(query: String): Flow<String> { return flow { delay(1500) emit(gfgDataQuery) } }
Ahora, en QueryTextChangeStateFlow, usaremos los siguientes operadores:
Kotlin
gfgSerachView.getQueryTextChangeStateFlow() .debounce(600) .filter { serachQuery -> if (serachQuery.isEmpty()) { textViewResult.text = "Geeks" return@filter false } else { return@filter true } } .distinctUntilChanged() .flatMapLatest { serachQuery -> dataFromNetwork(serachQuery) .catch { emitAll(flowOf("Geeks")) } } .flowOn(Dispatchers.Default) .collect { result -> sometxtView.text = result }
Es hora de aprender por qué se usan los operadores anteriores y cómo funcionan cuando se combinan.
Reconociendo Operadores
- Debounce : El operador de rebote se usa con una constante de tiempo en este caso. Cuando el usuario escribe «a», «ab» o «abc» en un corto período de tiempo, el operador de rebote maneja el caso. Como resultado, habrá una gran cantidad de llamadas de red. Sin embargo, el usuario está finalmente interesado en el resultado de búsqueda «abc». Como resultado, los resultados de «a» y «ab» deben descartarse. Idealmente, no debería haber llamadas de red para «a» y «ab» porque el usuario las escribió en un período de tiempo muy corto.
- Filtro : en este caso, el operador de filtro se usa para filtrar la string no deseada, que es una string vacía, para evitar realizar una llamada de red innecesaria.
- El distintivoUntilChanged: simplemente se usa para evitar llamadas duplicadas en la capa de red deseada. Suponga que la consulta de búsqueda en curso más reciente fue «abc», y el usuario eliminó «c» antes de escribir «c» nuevamente. Así que es «abc» una vez más. De lo contrario, cualquier llamada de red adicional hará que la búsqueda devuelva una consulta duplicada, lo que aumentará la carga en el servidor y, por lo tanto, evitará que la fuente emita elementos consecutivos duplicados.
- FlatMapLatest: esto se usa para que todos los resultados obsoletos obtenidos previamente no se muestren a los usuarios en una situación como una caída de la red. Suponga que la consulta de búsqueda más reciente fue «ab», hay una llamada de red en curso para «ab» y el usuario escribió «abc». Entonces ya no estamos interesados en el resultado de «ab». Solo nos preocupa el resultado de «abc». Como resultado, flatMapLatest viene al rescate. Solo devuelve los resultados de la consulta de búsqueda más reciente e ignora el resto.
GeekTip: tenga en cuenta que si hay un error en flatMapLatest, pasamos el resultado vacío. Esto se puede cambiar en función de nuestras necesidades.
De esta manera, podemos implementar la función de búsqueda instantánea en una aplicación de Android utilizando los operadores de flujo de Kotlin.
Publicación traducida automáticamente
Artículo escrito por therebootedcoder y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA