Categorías: Programación

Cree diseños personalizados para aplicaciones de Android con Jetpack Compose

Los diseños se pueden describir como contenedores que albergan objetos de vista, como botones, campos de texto, imágenes, etc. – que vemos en la interfaz de usuario de una aplicación. Definen cómo se organizan y muestran las vistas en la interfaz de usuario de una aplicación.

Jetpack Compose, el kit de herramientas de interfaz de usuario moderno de Android, proporciona algunos tipos de diseño comunes que los desarrolladores pueden usar. Sin embargo, también puede usar Jetpack Compose para crear diseños personalizados según sus necesidades.

Aprendamos más sobre diseños personalizados para aplicaciones de Android y cómo crearlos usando Jsatisetpack Compose. En este articulo:

Por qué debería saber cómo crear diseños personalizados

Jetpack Compose ofrece muchas herramientas de desarrollo para crear aplicaciones de Android más rápidas, incluidas varias opciones de diseño. En ocasiones, puede implementar los requisitos de diseño para la interfaz de usuario de una aplicación utilizando estos diseños existentes en Jetpack Compose.

Sin embargo, estos arreglos existentes no siempre cumplen con los requisitos de diseño del proyecto. En tales casos, necesita saber cómo crear un diseño personalizado para cumplir con los requisitos exactos de su proyecto.

Descripción general de los diseños en Jetpack Compose

Algunos diseños comunes en Jetpack Compose son:

  • Caja: un diseño que coloca sus vistas sobre otra
  • Columna: un diseño que coloca sus vistas en una secuencia vertical
  • Línea: un diseño que coloca sus vistas en una secuencia horizontal
  • ConstraintLayout: un diseño que coloca sus vistas en relación con otras

Recientemente, LazyVerticalGrid y LazyHorizontalGrid, que eran diseños de cuadrícula que se estaban probando, se lanzaron por completo.

Esta actualización viene con un diseño nuevo y emocionante llamado LazyLayout. Es un diseño que compone y presenta solo los elementos que se necesitan actualmente; en otras palabras, los elementos que pueden estar visibles en la pantalla de un dispositivo en un momento dado.

Puede usar diseños perezosos para crear diseños desplazables efectivos. Las variantes de LazyLayout incluyen:

  • LazyList, que muestra listas desplegables en:
  • LazyGrid, que muestra cuadrículas de desplazamiento en:

Sé que has visto mucho la palabra «perezoso», y no, eso no significa que estos diseños no quieran realizar sus funciones (como algunos de nosotros hacemos🙃). En cambio, solo significa que un diseño perezoso realizará su función solo cuando sea necesario. En otras palabras, es realmente efectivo.

Esta eficiencia es la razón por la cual los diseños perezosos se utilizan para diseños que tienen la intención de mostrar una gran cantidad de vistas, lo que les permite organizarse y desplazarse fácilmente en listas y cuadrículas.

Pasos para crear un diseño personalizado en Jetpack Compose

Para que entienda de manera efectiva el proceso de creación de su propio diseño, usaré un ejemplo simple. Vamos a crear un diseño que me gusta llamar ReverseFlowRow.

Este diseño simplemente coloca sus vistas una al lado de la otra, moviéndose a la siguiente fila cuando se llena la fila actual. Sin embargo, comienza a organizar sus vistas desde la posición final hasta la posición inicial de la pantalla, en otras palabras, de derecha a izquierda:

Creo que ese diseño debería usarse para los botones AlertDialog en Jetpack Compose para cumplir con las pautas de Material Design.

Actualmente, se usa un diseño similar, pero va desde la posición inicial hasta la posición final de la pantalla, lo que no cumple con estas pautas. Puede encontrar el problema que presenté con IssueTracker.

Más artículos interesantes de LogRocket:

La teoría detrás de los diseños Jetpack Compose para aplicaciones de Android

Para mostrar las vistas en la pantalla, Jetpack Compose compone el árbol de nodos de la interfaz de usuario (que representan las vistas), presenta cada vista en el árbol de la interfaz de usuario y dibuja cada una de ellas en la pantalla.

A los efectos de este artículo, solo nos interesa el diseño de las vistas, ya que podemos manejar la creación de un diseño personalizado durante este proceso. El proceso de diseñar vistas en un diseño es un proceso de tres pasos:

  • Medir todas las vistas de diseño (es decir, niños)
  • Decidir sobre el tamaño del diseño
  • Coloque a los niños dentro de los límites del diseño

Uso del diseño componible

En Jetpack Compose, el diseño de las vistas se puede lograr mediante el diseño componible, que se define como:

@Composable inline fun Layout(
    content: @Composable @UiComposable () -> Unit,
    modifier: Modifier = Modifier,
    measurePolicy: MeasurePolicy
)

El parámetro de contenido especifica las vistas (llamadas Componibles) que desea que aparezcan en este diseño. El parámetro modificador se usa para definir ciertos cambios de diseño, que se pueden pasar desde la vista principal o componible.

La parte más importante del código anterior es MeasurePolicy, que define la medida de las vistas secundarias, el tamaño del diseño y la ubicación de las vistas secundarias en el diseño.

Así que nuestro ReverseFlowRow comenzará así:

@Composable
fun ReverseFlowRow(
    content: @Composable () -> Unit
) = Layout(content) { measurables, constraints ->
    // measuring children, layout sizing, and placing children takes place here.
}

Puede notar que hemos representado MeasurePolicy como una lambda. Esto es posible porque MeasurePolicy es una interfaz funcional.

También en el código anterior, medible es la lista de elementos secundarios que deben medirse, mientras que las restricciones son los límites de diseño del elemento principal.

Medir todas las vistas en un diseño personalizado

Medimos a cada hijo con restricciones llamando a medida(restricciones) en cada uno de ellos. Esto devuelve un Placeable, que es un diseño secundario que puede ser colocado por su diseño principal.

val placeables = measurables.map { measurable ->
    // Measure each child.
    measurable.measure(constraints)
}

Tenga en cuenta que usamos las restricciones del padre al medir a cada hijo. Esto permite que cada niño pueda usar todo el espacio en la casa de los padres si es posible.

Agregar restricciones de tamaño al diseño personalizado

A continuación, establecemos el tamaño del diseño llamando al método layout() y especificando al menos su ancho y alto.

layout(constraints.maxWidth, constraints.maxHeight) {
   // Placement of children occurs here.
}

Aquí hemos utilizado el ancho y el alto máximos de la restricción principal. Por lo tanto, dependiendo de las restricciones del padre, este diseño puede o no ocupar toda la pantalla.

Colocar vistas en el diseño

Finalmente, colocamos los hijos medidos, también llamados colocables, en el diseño llamando al método placeRelative().

Este método debe usarse si desea reflejar automáticamente su diseño cuando cambia la dirección del diseño del dispositivo; en otras palabras, de izquierda a derecha a derecha a izquierda y viceversa.

Tenga en cuenta que puede obtener el LayoutDirection actual en el receptor layout(). Esto puede ser útil si no desea reflejar automáticamente su diseño cuando cambia la dirección del diseño, sino decidir cómo desea colocar sus vistas en cada dirección del diseño.

Si no desea que su diseño se refleje automáticamente en función de la dirección del diseño, use el método place() en su lugar.

// Track the x and y co-ordinates we have placed children up to.
var yPosition = 0
var xPosition = constraints.maxWidth

// Place children in the parent layout.
placeables.forEach { placeable ->
    if (placeable.width < xPosition) {
        // There is still enough space in the current row to add the next child.
        xPosition -= placeable.width
    } else {
        // Space left in the current row is not enough for the child. 
        // Move to the next row.
        yPosition += placeable.height
        xPosition = constraints.maxWidth - placeable.width
    }
    // Position child on the screen.
    placeable.placeRelative(xPosition, yPosition)
}

Como puede ver, necesitamos hacer un seguimiento de las coordenadas x e y que se usan para indicar dónde debe comenzar la colocación de cada niño. Esto nos permitirá colocar a un niño junto a otro y saber cuándo pasar a la siguiente fila o fila.

Código final del proyecto Jetpack Compose para el diseño personalizado de la aplicación de Android

Nuestro diseño completo se verá así:

@Composable
fun ReverseFlowRow(
    mainAxisSpacing: Dp,
    crossAxisSpacing: Dp,
    content: @Composable () -> Unit
) = Layout(content) { measurables, constraints ->
    // 1. The measuring phase.
    val placeables = measurables.map { measurable ->
        measurable.measure(constraints)
    }

    // 2. The sizing phase.
    layout(constraints.maxWidth, constraints.maxHeight) {
        // 3. The placement phase.
        var yPosition = 0
        var xPosition = constraints.maxWidth

        placeables.forEach { placeable ->
            if (placeable.width < (xPosition + mainAxisSpacing.roundToPx())) {
                xPosition -= (placeable.width + mainAxisSpacing.roundToPx())
            } else {
                yPosition += (placeable.height + crossAxisSpacing.roundToPx())
                xPosition = constraints.maxWidth - placeable.width - mainAxisSpacing.roundToPx()
            }
            placeable.placeRelative(xPosition, yPosition)
        }
    }
}

¿Notó que agregué dos nuevas propiedades: mainAxisSpacing y crossAxisSpacing? Estos se utilizan para agregar espacio entre cada niño en el diseño en las direcciones horizontal y vertical, respectivamente.

Probando nuestro diseño personalizado

Para obtener una vista previa de nuestro diseño, podemos envolverlo en una función componible anotada con @Preview. Esto nos permite ejecutar un diseño de muestra sin la configuración adicional requerida para una aplicación de Android. Agreguemos también algunas vistas de texto/componibles en nuestro diseño para ver cómo los muestra:

@Preview
@Composable
fun ReverseFlowRowPreview() {
    ReverseFlowRow(mainAxisSpacing = 16.dp, crossAxisSpacing = 16.dp) {
        Text("First", fontSize = 20.sp, style = TextStyle(background = Color.Red))
        Text("Second", fontSize = 20.sp, style = TextStyle(background = Color.LightGray))
        Text("Third", fontSize = 20.sp, style = TextStyle(background = Color.Blue))
        Text("Fourth", fontSize = 20.sp, style = TextStyle(background = Color.Green))
        Text("Fifth", fontSize = 20.sp, style = TextStyle(background = Color.Gray))
        Text("Sixth", fontSize = 20.sp, style = TextStyle(background = Color.Yellow))
        Text("Seventh", fontSize = 20.sp, style = TextStyle(background = Color.Cyan))
        Text("Eight", fontSize = 20.sp, style = TextStyle(background = Color.Magenta))
        Text("Ninth", fontSize = 20.sp, style = TextStyle(background = Color.DarkGray))
    }
}

Ejecutar la vista previa da los siguientes resultados:

Aunque en este ejemplo usamos vistas de texto/compuestos, este diseño personalizado de Jetpack Compose también funcionará con otros elementos componibles de Jetpack Compose. También puede usar los conceptos y seguir los pasos de este tutorial para crear su propio diseño personalizado.

Conclusión

Eso es más o menos lo que implica crear su propio diseño. Este ejemplo considera un escenario de caso normal, como el diseño requerido para los botones en un AlertDialog, pero se puede mejorar para adaptarse a más escenarios de caso, como una situación en la que los niños tienen diferentes alturas.

Si usa el diseño ReverseFlowRow que creamos tal como está con niños de diferentes tamaños, habrá cierta superposición entre ellos. Se necesita código adicional para acomodar tal caso. Si desea completar este mini desafío, publique el código actualizado en los comentarios a continuación.

WP Dev JaGonzalez

Hijo, esposo y padre de un hermoso niño. Amante de los animales, la tecnología, informática y programación. Si tienes alguna duda, inquietud, comentario o deseas comunicarte directamente conmigo, puedes enviarme un correo electrónico a admin@jagonzalez.org

Compartir
Publicado por
WP Dev JaGonzalez

Entradas recientes

iPhone Hackeado: Qué Hacer para Proteger tu Dispositivo y Asegurar tu Seguridad

¿Has notado aplicaciones desconocidas o un drenaje inesperado de la batería? Estos podrían ser indicios…

2 meses hace

Cómo Restablecer un iPhone a su Estado de Fábrica

Saber cómo Restablecer un iPhone a su Estado de Fábrica es clave para solucionar problemas…

2 meses hace

Motorola planea lanzar al menos dos nuevos teléfonos Moto G en septiembre

Motorola ha confirmado el lanzamiento de Moto G84 5G y Moto G54 5G en India,…

1 año hace

El equipo de WizardLM afirma que un modelo de IA de terceros les robó el trabajo

Recuerde WizardCoder, ¿el codificador de IA que cubrimos recientemente aquí en Windows Report? Nos jactamos…

1 año hace

Las fallas del complemento Jupiter X Core amenazaron a 172.000 sitios web con apropiaciones de cuentas

Los investigadores han descubierto numerosos fallos de seguridad en el complemento WordPress Jupiter X Core…

1 año hace

Consola portátil Xbox: aquí tienes todo lo que necesitas saber al respecto

Para solucionar problemas del sistema de PC con Windows, necesitará una herramienta dedicada Fortect es…

1 año hace