Resumen de Android Jetpack Compose

Introduccion

Jetpack Compose es una nueva forma de construir una interfaz de usuario nativa. El método de escritura es muy similar al de Flutter. Los estudiantes que conocen Flutter pueden comenzar rápidamente.
Sitio web oficial: https://developer.android.com/jetpack/compose
demostración oficial: https://github.com/android/compose-samples
introducción oficial: https://developer.android.com/jetpack/compose/setup

Entorno y versión

El soporte mínimo es Android API 21, versión 5.0, que debe usar el lenguaje kotlin, y la versión mínima es Android Studio 4.0.
Jetpack Compose se encuentra actualmente en la etapa experimental, ahora es 0.1-dev2, y se estima que pasará otro año antes de la versión oficial de 1.0.
Las versiones posteriores pueden agregar más funciones de kotlin, enriquecer la animación y otros problemas de rendimiento.

Acerca de cómo usar en proyectos existentes:
https://developer.android.com/jetpack/compose/setup#add-compose

Como usar

Redactar un nuevo proyecto vacío directamente en el AS 4.0, hay un código de ejemplo:
Inserte la descripción de la imagen aquí
añadido antes de la función @Composeanotaciones, puede volver a un aleteo similar en los widgets de interfaz de usuario
añadir @Composefunciones de anotación puede llamar a los demás, estas funciones serán compilados plug-in de procesamiento Entonces, si una función no genera la IU, entonces no use esta anotación.
@PreviewLa anotación se puede previsualizar en tiempo real a la derecha. Después de cambiar la función, actualice una previsualización. La función externa a la que se agrega la anotación no puede tener parámetros, pero una función con parámetros se puede anidar dentro para previsualizar. Puede @Previewagregar un nombre en la parte posterior, como:@Preview("Text preview")

Los conceptos de Columna y Fila son los mismos que en Flutter, incluido el tamaño del concepto mainAxisSizey la alineación del eje principal y el eje secundario crossAxisAlignment, y un ejemplo de código:

@Composable
fun MyScreenContent(
    names: List<String> = listOf("Android", "there"),
    counterState: CounterState = CounterState()
) {
    Column(crossAxisAlignment = CrossAxisAlignment.Center
      crossAxisSize = LayoutSize.Expand,
        mainAxisSize = LayoutSize.Expand) {
        for (name in names) {
            Greeting(name = name)
            Divider(color = Color.Black)
        }
        Divider(color = Color.Transparent, height = 32.dp)
        Counter(counterState)
    }
}

@Preview("MyScreen preview")
@Composable
fun DefaultPreview() {
    MyApp {
        MyScreenContent()
    }
}

Puede usar HeightSpacer(24.dp)o WeightSpacer(24.dp)para agregar directamente un intervalo de ancho y alto

De acuerdo con las sugerencias oficiales, podemos dividir la interfaz de usuario en múltiples funciones de composición pequeñas. Cada función eventualmente será compilada por el complemento para generar una vista, y luego estas funciones de composición se pueden reutilizar.

@Composable
fun MyScreenContent(
    names: List<String> = listOf("Android", "there"),
    counterState: CounterState = CounterState()
) {
    Column(modifier = ExpandedHeight, crossAxisAlignment = CrossAxisAlignment.Center) {
        Column(modifier = Flexible(1f), crossAxisAlignment = CrossAxisAlignment.Center) {
            for (name in names) {
                Greeting(name = name)
                Divider(color = Color.Black)
            }
        }
        Counter(counterState)
    }
}

En Column, puede establecer ExpandedHeight en el modificador de parámetros, de manera similar al significado de establecer la altura match_parent, el ancho es el mismo.

Acerca de cómo usar Theme y personalizar Theme

Hay muchos colores y estilos de fuente en MaterialTheme. Después de ajustar MaterialTheme en la capa externa, puede usar los datos del tema en la función interna de composición, como:style = +themeTextStyle { h1 }

@Composable
fun Greeting(name: String) {
    Text (
        text = "Hello $name!",
        modifier = Spacing(24.dp),
        style = +themeTextStyle { h1 }
        color = +themeColor { surface }
    )
}

Puede modificar un determinado valor de atributo en un tema existente utilizando la función de copia, como:

textStyle = (+themeTextStyle { body1 }).copy(color = Color.Yellow)

Tema personalizado

import androidx.compose.Composable

@Composable
fun CustomTheme(children: @Composable() () -> Unit) {
    // TODO 
}
import androidx.compose.Composable
import androidx.ui.core.CurrentTextStyleProvider
import androidx.ui.graphics.Color
import androidx.ui.material.MaterialColors
import androidx.ui.material.MaterialTheme
import androidx.ui.text.TextStyle

val green = Color(0xFF1EB980.toInt())
val grey = Color(0xFF26282F.toInt())
private val themeColors = MaterialColors(
    primary = green,
    surface = grey,
    onSurface = Color.White
)

@Composable
fun CustomTheme(children: @Composable() () -> Unit) {
    MaterialTheme(colors = themeColors) {
        val textStyle = TextStyle(color = Color.Red)
        CurrentTextStyleProvider(value = textStyle) {
            children()
        }
    }
}

Efectos y memo

El papel de la nota:

1. Cuando las recomposiciones (es decir, cuando los datos del Modelo dentro del componente UI cambien, el componente UI se reconstruirá), guarde el valor de estado, de la siguiente manera:

@Composable
fun MyScreenContent(
    names: List<String> = listOf("Android", "there"),
    counterState: CounterState = CounterState()
) { ... }

Hay un problema con el código anterior. Cuando se reconstruye, se perderá el valor original de counterState, cada vez que un nuevo objeto counterState.
Puede resolver el problema después de modificarlo utilizando memo de la siguiente manera:

@Composable
fun MyScreenContent(
    names: List<String> = listOf("Android", "there"),
    counterState: CounterState = +memo { CounterState() }
) { ... }

2. Al reorganizar, recuerde algunos resultados de cálculo internos para evitar cálculos múltiples.

Si necesita realizar cálculos en el medio de la composición, pero no desea realizar cálculos cada vez que recombina la función, puede recordar el cálculo, incluso si la función Composable se recombina, el cálculo no se volverá a realizar.

@Composable
fun Greeting(name: String) {

    val formattedName = +memo { name.substringBefore(" ").toUpperCase() }

    Text (
        text = "Hello $formattedName!",
        modifier = Spacing(24.dp),
        style = +themeTextStyle { h3 }
    )
}

@Preview
@Composable
fun DefaultPreview() {
    MaterialTheme {
        Greeting("Android 10")
    }
}

Por ejemplo, el proceso de cálculo de formattedName aquí no se repetirá después de usar memo, pero hay un error escrito de esta manera. Si se pasa otro parámetro en la segunda llamada, porque memo reutiliza el resultado original, lo hará Provoca un error, por lo que para los parámetros que deben modificarse, memo puede usarse de la siguiente manera:

@Composable
fun Greeting(name: String) {

    val formattedName = +memo(name) { name.substringBefore(" ").toUpperCase() }

    Text (
        text = "Hello $formattedName!",
        modifier = Spacing(24.dp),
        style = +themeTextStyle { h3 }
    )
}

@Modelo anotado

Después de que la anotación del modelo marca una clase de datos, puede supervisar directamente los cambios de datos en la función Componer y actualizar automáticamente la pantalla,
como:
definición:

@Model 
class CounterState(var count: Int = 0)

Uso:

@Composable 
fun Counter(state: CounterState) {
    Button(
        text = "I've been clicked ${state.count} times",
        onClick = {
            state.count++
        }
    )
}

Promoción de estado, flujo de datos hacia abajo, flujo de eventos hacia arriba

@Model
class FormState(var optionChecked: Boolean)

@Composable
fun Form(formState: FormState) {
    Checkbox(
        checked = formState.optionChecked,
        onCheckedChange = { newState -> formState.optionChecked = newState })
}

在上面代码中,Checkbox的选中状态,在Checkbox和Form中都不保存,而改为由外部传入,原因是此时外部可能需要使用当前的状态值,那么由外部来创建并传递该参数到Compose函数中,这使得外部调用者提升了状态

⚠️ Nota: En las funciones componibles, se debe revelar el estado que puede ser útil para llamar a la función, ya que este es el único método que se puede usar o controlar, llamado promoción estatal.

El concepto de promoción estatal es el mismo que Flutter. En el futuro, también debería introducir bibliotecas de administración de estado relacionadas como Provider, BLOC o Redux en Flutter, porque la forma de anotación Compose + Model es una idea MVVM y necesita una conveniencia. Una biblioteca tripartita de gestión del estado de datos hace esto.

Con respecto al flujo de datos: la función Composable principal puede controlar sus datos secundarios. La interfaz de usuario de Sub Compose no debe leerse desde variables globales o almacenamiento de datos global. Las funciones componibles solo deben recibir la información requerida, por lo que deben ser lo más simples posible, en lugar de llamar a todo lo que la función componible principal puede proporcionar.

@Composable
fun MultipleGreetings(user: User = +memo { User("name", "surname") }) {
    Column {
        Greeting("${user.firstName} ${user.lastName}")
        Greeting("Android 10")
        Button(text = "Change name", onClick = {
            user.firstName = "Changed"
            user.lastName = "New surname"
        })
    }
}

@Composable
fun Greeting(name: String) {

    val formattedName = +memo(name) { name.substringBefore(" ").toUpperCase() }

    Text (
        text = "Hello $formattedName!",
        modifier = Spacing(24.dp),
        style = +themeTextStyle { h3 }
    )
}

比如上面代码中,Greeting从调用方Compose函数(MultipleGreetings)获取数据,作为参数传入,且Greeting只接收一个String,并不是整个User对象。

Evento que pasa

El evento continúa durante la devolución de llamada lambda. Cuando la función Composable secundaria recibe un evento, el cambio debe propagarse nuevamente al Composable que se preocupa por la información.

En nuestro ejemplo, podemos hacer que se pueda hacer clic en Saludo envolviendo el contenido de Saludo en una función en la que se puede hacer clic (disponible en la biblioteca) que toma un oyente onClick como parámetro. Sin embargo, Saludo es una función reutilizable, no sabe cómo manejar la interacción del usuario. Debe usar lambda para propagar esta información desde la parte inferior de la jerarquía (Composable en el que se puede hacer clic en Saludo) a las funciones Composable en la parte superior, que saben cómo manejar esta información, como se muestra en el siguiente ejemplo:

@Composable
fun MultipleGreetings(user: User = +memo { User("name", "surname") }) {

    val onClick = {
        user.firstName = "Changed"
    }

    Column {
        Greeting("${user.firstName} ${user.lastName}", onClick)
        Greeting("Android 10", onClick)
        Button(text = "Change name", onClick = onClick)
    }
}

@Composable
fun Greeting(name: String, onClick: () -> Unit) {

    val formattedName = +memo(name) { name.substringBefore(" ").toUpperCase() }

    Clickable(onClick = onClick) {
        Text (
            text = "Hello $formattedName!",
            modifier = Spacing(24.dp),
            style = +themeTextStyle { h3 }
        )
    }
}

Saludo le dice a MultipleGreetings que se hizo clic llamando a la lambda pasada por el padre como parámetro. Si ejecuta la aplicación, puede ver que al hacer clic en cualquier texto de saludo se propagarán los cambios y la instancia de saludo en la parte superior se reagrupará.

Inserte la descripción de la imagen aquí
Flujo de datos en componer aplicaciones.  Los datos fluyen hacia abajo con parámetros, los eventos fluyen hacia arriba con lambdas.
Flujo de datos en componer aplicaciones. Los datos fluyen hacia abajo con parámetros, los eventos fluyen hacia arriba con lambdas.


Componer y ver interoperabilidad existente

Las funciones escritas por Compose se pueden usar en XML, y la Vista existente de Android también se puede escribir en Compose, como:
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí
Resumen: Compose se basa en el método de escritura de Flutter y Swift UI, el código es conciso, puede previsualizar el efecto en tiempo real, a partir de 2019 El 19 de noviembre, la versión actual era solo 0.1. Se espera que después del lanzamiento oficial de 1.0, habrá más actualizaciones de funciones. Una pequeña demostración diaria se puede familiarizar primero con Compose.

Referencia:
https://codelabs.developers.google.com/codelabs/jetpack-compose-basics/#0

Excelente! El último desarrollo de la biblioteca de componentes de la interfaz de usuario de Android Jetpack Compose, escrita exactamente como Flutter

¡El último progreso de Android Studio 4.0, estas nuevas características son increíbles!

82 artículos originales publicados · Me gusta 86 · Visita 110,000+

Supongo que te gusta

Origin blog.csdn.net/unicorn97/article/details/103137105
Recomendado
Clasificación