Jetpack Compose estado deconstruido | de Yves Kalumé | diciembre 2022

En el sistema de visualización (XML), cada elemento de la interfaz de usuario es un objeto que contiene un estado interno que se puede actualizar llamando a un setter o cambiando una propiedad. Tomemos el ejemplo de una aplicación que muestra un número que se incrementará cuando se hace clic en un botón. .text = countbutton.setOnClickListener {count++textView.text = count}El valor de TextView es un estado interno de este elemento y solo se puede cambiar llamando a un setter en este objeto con el nuevo valor. Con Jetpack compose, todo será diferente, los componibles son funciones que obtienen los datos que contienen como argumentos que deben usar para representar la interfaz de usuario, y cuando los datos cambian, las funciones se ejecutan nuevamente con los nuevos argumentos (estamos hablando de recomposición).

¡Jetpack Compose es bastante inteligente! Simplemente vuelve a ejecutar el componible usando el valor modificado, que es «recomposición inteligente”.

En nuestro ejemplo, la versión Jetpack Compose de nuestra interfaz de usuario se ve así: @Composablefun Counter() {var count = 0Text(«$count»)Button(onClick = { count++ }) {Text(text = «Click Me»)} }Pero el código anterior no funcionará (y entenderás por qué 👨🏾‍💻). Tenga en cuenta que no todos los valores inician una recomposición cuando cambian, solo los estados pueden hacerlo. Un estado es solo un observable de tipo Estado. No se requiere nada complicado para crear un estado, solo necesita llamar a la función mutableStateOf, que toma un observable de tipo MutableState devuelve cuya firma Interface MutableState : Estados< ist T> {override var value: T}mutableStateOf toma el valor inicial entre paréntesis, y solo necesita llamar a la propiedad value para acceder o cambiar el valor. Ahora así es como se verá nuestro código @Composablefun Counter() {var count = mutableStateOf(0)Text(«${count.value}»)Button(onClick = { count.value++ }) {Text(text = «Click Yo»)}}Este código tampoco funcionará correctamente. Debe saber que la recomposición puede ocurrir en cualquier momento, el elemento de contador componible se puede recomponer en cualquier momento, y si cambia la variable de contador, la función de contador se puede recomponer y volver a ejecutar, lo que significa que todo el código es allí nuevamente ejecutado, lo que reinicia el contador a 0. Si ejecutas este código en Android St udio, te mostrará un error diciéndote lo mismo que te acabo de decir. Entonces, ¿cómo puede recordar un estado incluso si la función se ejecuta nuevamente?a través del uso Recuerda ! La función de recordar permite que un componible mantenga un valor en la memoria a través de las recomposiciones. En nuestro caso, evita que el recuento se restablezca a 0 y mantiene el valor incrementado) }Text(«${count.value}»)Button(onClick = { count.value++ }) {Text(text = «Click Me» )}}¡Esta vez nuestro código funciona! 🎉Podemos hacerlo aún más conciso usando el delegado con by . Esto nos evita usar .value cada vez que contamos.@Composablefun Counter() { var count by Remember { mutableStateOf(0) }Text(» $count»)Button(onClick = { count++ }) {Text(text =»Click Yo»)}}Debe realizar las siguientes importaciones para usar byimport androidx.compose.runtime.getValueimport androidx.compose.runtime.setValue

Si bien «Recordar» lo ayuda a mantener el estado en las recomposiciones, el estado no se mantiene en los cambios de configuración (por ejemplo, la rotación de la pantalla). Para hacer esto, debe usar «RememberSaveable». RememberSaveable guarda automáticamente cualquier valor que se pueda guardar en un paquete. Para otros valores, puede pasar un objeto protector personalizado.

Para que Jetpack compose use un valor como estado, debe codificarlo en un Estado emitir y componer tiene funciones que le permiten convertir ciertos tipos de observables en un estado. Puedes convertir datos en vivo, flujo y RxJava2.fechas de vidaValor: Cadena de liveData.observeAsState(«inicial»)FlujoValor: Cadena de stateFlow.collectAsState()RxJava2Valor de completable.subscribeAsState()

Al usar observables personalizados, puede crear extensiones de función para convertirlos en un estado

Componible con estado

Se dice que un componible como Counter tiene estado porque contiene un recuerdo con un estado, la función que lo llama no tiene acero para ese estado. Aquí hay un ejemplo: @Composablefun HomeScreen() {Counter()}HomeScreen no tiene acceso al valor de conteo, por lo que no se puede controlar ni cambiar, porque Counter lo bloquea en sí mismo. Todo funciona a la perfección en nuestro caso anterior, pero debes saber que los componibles con estado no siempre son ideales. No son fácilmente reutilizables, especialmente cuando la persona que llama necesita tener el control del estado, para eso necesita un apátrida componible

componible sin estado

Un componible sin estado es solo un componible que no incluye la inicialización del estado, pero lo obtiene como un parámetro a través de la función que lo llama. El mejor ejemplo de un componible sin estado es Compose TextField@Composablefun MyScreen() {var Text by Remember { MutableStateOf(«») }TextField(value = text,onValueChange = { newText ->text = newText})}El Textfield Composable no No contiene el texto ingresado, pero lo toma como un argumento y la persona que llama controla el valor del texto. Y cuando el cuadro de texto quiere cambiar el texto, solo necesita usar una devolución de llamada. Esto hace que TextField sea fácilmente reutilizable y comprobable, ya que los componibles que lo llaman pueden adaptar su comportamiento a sus especificaciones. La forma más fácil de crear un componible sin estado es elevar el estado.Cuando hablamos de estados en Jetpack Compose hay un concepto bastante importante que debes saber, es este levantamiento estatal.Volvamos a nuestro ejemplo de contador e intentemos aumentar su estado. @Composablefun Counter(count: Int) {Text(«$count»)Button(onClick = { count++ }) {Text(text = «Click Me») }} En su lugar de crear un estado dentro, esta vez lo pasamos como parámetro. Este código no funciona debido a count++ porque el valor recibido como parámetro no se puede cambiar dentro de la función (es un valor). Entonces, para lograr esto, pasaremos un segundo parámetro que será una función. @Composablefun Counter(count: Int, onIncrement: () -> Unit) {Text(«$count»)Button(onClick = { onIncrement() }) {Text(text = «Click Me»)}}Ahora la persona que llama puede controlar el estado @Composablefun HomeScreen() {var count by Remember { mutableStateOf(0) }Counter(count = count, onIncrement = { count++ } )} Nuestro contador ahora es reutilizable, y la función que lo llama puede controlar el estado por completo control. Incluso podemos tener un contador que aumente en 2.La vista previa de HomeScreen y Screen2

Nota: Puede pasar múltiples funciones como argumentos a un componible, y una función puede cambiar de forma según el caso de uso. Por ejemplo, podemos convertir onIncrement: () → Unit a onIncrement: (Int) → Unit para incrementar el número dentro del contador y recuperar el nuevo valor.

@Composablefun Counter(count: Int,onIncrement: (Int) -> Unit) {Text(«${count}»)Button(onClick = { onIncrement(count + 1) }) {Text(text = «Click Me») }}@Composablefun HomeScreen() {var count by Remember { mutableStateOf(0) }Counter(count = count, onIncrement = { count = it } )} Este ejemplo corresponde a lo que se hace en el compose TextField con onValueChange: (String ) -> Función de unidad. Los estados son un concepto muy importante con Jetpack Compose o el paradigma declarativo en general. Su mal uso también puede afectar el rendimiento de su aplicación. A continuación hay algunos enlaces a recursos que serán útiles más adelante.

Deja una respuesta

Tu dirección de correo electrónico no será publicada.