¿Cómo encadenar transformaciones en Android al usar datos en vivo?

Dada la siguiente configuration:

Tengo 2 repositorys: Repositorio A y Depósito B, ambos devuelven datos en vivo.

Tengo un ViewModel que usa ambos repositorys.

Quiero extraer algo del Repositorio A y, dependiendo del resultado, quiero tomar algo del Repositorio B y luego transformar el resultado antes de regresar a la IU.

Para esto he estado mirando las classs de Transformación de LiveData . Los ejemplos muestran una transformación única del resultado; sin embargo, quiero algo en la línea de encadenar dos transformaciones. ¿Cómo puedo lograr esto?

Intenté configurar algo así pero obtuve una discrepancia de tipo en el segundo bloque de transformación:

internal val launchStatus: LiveData<String> = Transformations .map(respositoryA.getData(), { data -> if (data.isValid){ "stringA" } else { //This gives a type mismatch for the entire block Transformations.map(repositoryB.getData(), { result -> result.toString() }) } }) 

(También avíseme si hay un enfoque alternativo / recomendado para tomar algo para encadenar estas llamadas, es decir, tomar algo de A y luego tomar algo de B, dependiendo del resultado de A, y así sucesivamente)

Yo trataría de usar SwitchMap en lugar de map:

Similar a map (), aplica una function al valor almacenado en el object LiveData y desenvuelve y distribuye el resultado en sentido descendente. La function pasada a switchMap () debe devolver un object LiveData.

Puede transformar los datos usando switchmap . Aquí hay una documentation de ejemplo.

Usé MediatorLiveData para resolver este problema.

MediatorLiveData puede LiveData otros objects LiveData y reactjsr ante ellos.

En lugar de observar cualquiera de los repositorys. Creé myData (instancia de MediatorLiveData) en mi class ViewModel y ViewModel que mi vista observe este object. Luego agrego el Repositorio A como fuente inicial y observo eso y solo agrego el Repositorio B si el resultado de A lo requiere. Esto me permite mantener las transformaciones asociadas con los datos en vivo de cada uno de los repos y aún procesar cada resultado en el order correcto. Ver a continuación para la implementación:

 internal val myData: MediatorLiveData<String> = MediatorLiveData() private val repoA: LiveData<String> = Transformations.map( respositoryA.getData(), { data -> if (data.isValid) "stringA" else "" }) private val repoB: LiveData<String> = Transformations.map( repositoryB.getData(), { data -> "stringB" }) fun start() { myData.addSource(repoA, { if (it == "stringA") { myData.value = it } else { launchStatus.addSource(repoB, { myData.value = it }) } }) } 

Nota : La solución no cubre el caso en el que repoB podría agregarse varias veces, pero debería ser lo suficientemente simple de manejar.

  • burlarse de la respuesta anidada del server
  • Obtuvo NoClassDefFoundError al pasar el map de lambda
  • Cómo llamar al constructor String de Java (char , int offset, int length) de Kotlin?
  • La mejor forma de implementar el patrón de visitante en Kotlin
  • Kotlin: ¿A dónde deberían ir las funciones de nivel superior?
  • La function en línea de Kotlin no funciona correctamente
  • ¿Conversión de Kotlin SAM con una interfaz Java interna privada?
  • Kotlin: ambigüedad de resolución de sobrecarga lambda y sobrecarga
  • Ejecución del progtwig Java y Kotlin con la biblioteca de time de ejecución Kotlin en el classpath
  • kodein: el valor de los datos inyectados no es el valor recuperado de los datos
  • Kotlin: ¿Qué características de Java 8 aún no son compatibles?