[Android] FlowBinding: use Coroutine Flow para crear una interfaz de usuario receptiva

Inserte la descripción de la imagen aquí

RxBinding


El desarrollo de Android de hoy en día está introduciendo cada vez más conceptos como MVI, Redux y flujo de datos unidireccional, y se esfuerza por lograr una experiencia de desarrollo de interfaz de usuario receptiva como marcos de front-end como react.

Además de soluciones radicales como Jetpack Compose, el cliente también tiene algunas soluciones adaptadas a las condiciones locales, como RxBinding, a través de la cooperación de RxJava y Android View, reemplazando OnClickListener con Observable, para lograr un desarrollo de UI impulsado por eventos de manera más eficiente.

findViewById<Button>(R.id.button).clicks().subscribe {
    
    
    // handle button clicked
}

FlowBinding


kotlinx.coroutines ha agregado la biblioteca Flow desde 1.3, que puede procesar datos de transmisión de manera receptiva en CoroutineScope, que se puede llamar la versión de corrutina de RxJava. En consecuencia, ha habido muchos proyectos excelentes de RxJava => Flow. El FlowBinding presentado hoy es uno de ellos: la versión Flow de RxBinding.

// Platform bindings
implementation "io.github.reactivecircus.flowbinding:flowbinding-android:${flowbinding_version}"
// AndroidX bindings
implementation "io.github.reactivecircus.flowbinding:flowbinding-appcompat:${flowbinding_version}"
implementation "io.github.reactivecircus.flowbinding:flowbinding-core:${flowbinding_version}"
implementation "io.github.reactivecircus.flowbinding:flowbinding-drawerlayout:${flowbinding_version}"
implementation "io.github.reactivecircus.flowbinding:flowbinding-navigation:${flowbinding_version}"
implementation "io.github.reactivecircus.flowbinding:flowbinding-recyclerview:${flowbinding_version}"
implementation "io.github.reactivecircus.flowbinding:flowbinding-swiperefreshlayout:${flowbinding_version}"
implementation "io.github.reactivecircus.flowbinding:flowbinding-viewpager2:${flowbinding_version}"
// Material Components bindings
implementation "io.github.reactivecircus.flowbinding:flowbinding-material:${flowbinding_version}"

Además de los controles estándar de Android, FlowBinding también admite varios controles en AndroidX y controles de materiales

Instrucciones

Supervise el evento OnClick en CoroutineScope:

uiScope.launch {
    
    
    findViewById<Button>(R.id.button)
        .clicks() // this returns a Flow<Unit>
        .collect {
    
    
            // handle button clicked
        }
}

kotlinx-coroutines-coreSe proporciona launchIn(scope)para simplificar scope.launch { flow.collect() }la redacción:

findViewById<Button>(R.id.button)
    .clicks() // binding API available in flowbinding-android
    .onEach {
    
    
        // handle button clicked
    }
    .launchIn(uiScope)

El uiScope en el ejemplo anterior representa CoroutineScope consistente con el ciclo de vida de actividad / fragmento, lo que evita eficazmente las pérdidas de memoria.

androidx.lifecycle:lifecycle-runtime-ktx:2.2.0Los atributos extendidos proporcionados por se pueden usar en el desarrollo real, LifecycleOwner.lifecycleScope: LifecycleCoroutineScopey las corrutinas en el alcance se pueden cancelar durante el onDestroy del ciclo de vida:

class ExampleActivity : AppCompatActivity() {
    
    
    
    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_example)
        findViewById<Button>(R.id.button)
            .clicks()
            .onEach {
    
    
                // handle button clicked
            }
            .launchIn(lifecycleScope) // provided by lifecycle-runtime-ktx 
            
    }
}

Principio de realización

El principio de realización es relativamente simple:

scope.launch {
    
    
    findViewById<Button>(R.id.button)
        .clicks() // this returns a Flow<Unit>
        .collect {
    
    
            // handle button clicked
        }
}

Pase callbackFlow, puede convertir una devolución de llamada a Flow para implementar el clicks()método anterior

fun View.clicks(): Flow<Unit> = callbackFlow 
    val listener = View.OnClickListener {
    
    
        offer(Unit)
    }
    setOnClickListener(listener)
    awaitClose {
    
     setOnClickListener(null) }
}

awaitClose{}Se ejecutará al final del flujo, por lo que puede darse de baja aquí para
offer()transmitir los datos al uso interno del SendChannelflujo, pero si el flujo está cerrado, se puede lanzar una excepción, por lo que se puede aumentar el procesamiento de captura de excepciones.

fun <E> SendChannel<E>.safeOffer(value: E) = !isClosedForSend && try {
    
    
    offer(value)
} catch (e: CancellationException) {
    
    
    false
}

El código completo es el siguiente:
Inserte la descripción de la imagen aquí

Al final


FlowBinding utiliza Coroutine Flow para crear un conjunto de bibliotecas de herramientas de interfaz de usuario receptivas y coopera con LifecycleScope para realizar el cierre de sesión automático para evitar pérdidas de memoria. Hoy en día, cuando Kotlin es popular, se recomienda usar FlowBinding en lugar de RxBinding, y usar esto como una oportunidad para explorar más escenarios de uso del uso de Flow en lugar de RxJava.

Supongo que te gusta

Origin blog.csdn.net/vitaviva/article/details/108901144
Recomendado
Clasificación