[Xamarin.Forms] Primer vistazo a FlexLayout

Introducción

Una de las grandes nuevas características que tendremos en Xamarin.Forms, ya disponible en paquetes Nightly, es FlexLayout.

En este artículo, vamos a realizar una introducción a este nuevo Layout, sus opciones y características principales.

Layouts de Xamarin.Forms

En Xamarin.Forms contamos con diferentes Layouts que nos permiten organizar y posicionar los diferentes elementos visuales que componen la interfaz de usuario.

Las clases Layout y Layout<T> en Xamarin.Forms son tipos especiales de Views que actúan como contenedores de otras Views o Layouts.

Layouts en Xamarin.Forms

¿Qué es FlexLayout?

Al trabajar con CSS en desarrollo web, para adoptar una sintaxis limpia para crear diseños adaptativos llegó Flexbox.

Flexbox proporciona una forma eficiente de distribuir, alinear y gestionar el espacio entre elementos incluso cuando el tamaño de la ventana o de cada elemento es dinámico o desconocido.

Basados en esta opción, contamos con un nuevo Layout llamado FlexLayout con gran cantidad de opciones para la gestión de la distribución y tamaño de elementos.

¿Por dónde empezamos?

Probablente sea tu primera pregunta. Comenzamos creando un nuevo proyecto Xamarin.Forms.

Tras crear el proyecto, actualizamos el paquete a la versión Nightly de Xamarin.Forms:

Xamarin.Forms Nightly

NOTA: Puedes ver como acceder a versiones Nightly de Xamarin.Forms en este enlace.

Basta con añadir en la página:

<FlexLayout>
</FlexLayout>

Para comenzar a trabajar con FlexLayout.

FlexLayout, propiedades

El comportamiento del Layout es diferente en base a sus propiedades. A continuación, vamos a revisar las propiedades fundamentales.

Direction

La propiedad Direction controla la dirección de los elementos. Los valores posible son:

  • Row
  • Column
  • RowReverse
  • ColumnReverse

Simplificando, esta propiedad permite definir como se distribuyen los elementos que contiene. Puede ser de forma horizontal, vertical o de forma invertida en ambas direcciones. La dirección predeterminada es horizontal, de izquierda a derecha.

NOTA: En el «mundo flexible» no se usa «horizontal» o «vertical» si no eje principal (main-axis) y eje transversal (cross-axis).

Aunque no se establezca de forma explícita, FlexLayout tiene como valor predeterminado Row.

Wrap

Contamos con los siguientes valores:

  • Wrap
  • NoWrap
  • Reverse

Pero…¿para qué lo usamos?.

Para entender correctamente esta propiedad vamos a crear un sencillo ejemplo. Dentro de un FlexLayout añadimos elementos:

Comenzando el ejemplo

Son textos de 24px de ancho. Por defecto, como hemos visto anteriormente se organizarán en formato de Row de izquierda a derecha.

Bien, vamos a duplicar los elementos. ¿Qué va a ocurrir?, ¿se salen elementos de pantalla?, ¿se ajusta el tamaño de todo?, ¿se dividen elementos a una nueva línea?.

Duplicamos elementos

Nada como probar, para tener la respuesta. El contenedor se adapta para poder contenedor todos los elementos hijos. Este es el comportamiento por defecto. Es decir, la propiedad Wrap tiene como valor predeterminado NoWrap.

Podemos modificar el comportamiento de forma sencilla:

Wrap

JustifyContent

Si hasta ahora piensas que todo tiene buena pinta, esta propiedad te va a gustar. Cuenta con las siguientes opciones:

  • Start
  • Center
  • End
  • SpaceBetween
  • SpaceAround
  • SpaceEvenly

Esta propiedad te puede recordar a la alineación de texto. Define como se organizan los elementos en el eje principal. El valor por defecto es Start. Con este valor los elementos se agrupan al inicio del eje principal.

Start

Por el contrario, la opción End agrupa los elementos al final del eje principal:

End

Centrados:

Center

La opción SpaceBetween mantiene el mismo espacio entre cada elemento:

SpaceBetween

SpaceAround, es similar a la opción anterior, los elementos se distribuyen uniformemente manteniendo además el mismo espacio alrededor (en ambos lados). Nota que el primer elemento tendrá una unidad de espacio con respecto al borde del contenedor, pero dos unidades con respecto al siguiente elemento (el siguiente elemento cuenta con su propio espacio).

SpaceAround

Por último, contamos con SpaceEvenly donde los elementos se distribuyen manteniendo el mismo espacio entre elementos y los bordes.

SpaceEvenly

AlignItems

Esta propiedad es similar a la anterior por lo que es rápida de asimilar. Los posibles valores son:

  • Start
  • Center
  • End
  • Stretch

Define el comportamiento predeterminado de cómo se colocan los elementos a lo largo del eje transversal (cross-axis).

El valor predeterminado es Stretch que se encargará de «estirar» los elementos para que rellenen toda la altura del contenedor. El resto de opciones hacen justo lo que imaginas, agrupan los elementos al inicio, centro o final del contenedor.

AlignContent

¿Recuerdas lo que pasaba al añadir más elementos al probar la propiedad relacionada con Wrap?. Utilizando Wrap tenemos un contenedor flexible multilínea.

Esta propiedad permite controlar la alineación de los elementos haciendo Wrapping. Nos permite controlar el espacio adicional en el eje transversal.

NOTA: Esta propuedad no tiene efcto cuando solo hay una línea de elementos.

Los valores posibles son:

  • Start
  • Center
  • End
  • Stretch
  • SpaceBetween
  • SpaceAround
  • SpaceEvenly

Como en AlignItems el valor por defecto es Stretch. Con este valor, los elementos se «estiran» para adaptarse al espacio disponible a lo largo del eje transversal.

Hemos visto anteriormente el resto de propiedades, sin embargo, hay en esta ocasión ligeras diferencias.

El valor Start alinea los elementos del contenedot al inicio del eje transversal. Recuerda que el eje transversal tiene como orden predeterminado de arriba hacia abajo. Por lo tanto, el valor End los coloca en la parte inferior (abajo) y Center en el centro.

Propiedades de cada elemento

Además de poder cambiar el comportamiento del Layout gracias a sus propiedades principales, podemos adaptar diferentes opciones utilizando propiedades de cada elemento.

FlexLayout.Grow

La gran aportación de FlexLayout es permitir que sus elementos sean «flexibles». Esta propiedad nos permite tener aún más control en este sentido. El valor de la propiedad puede ser desde cero a cualquier valor numérico positivo. Vamos a ver en que consiste.

Por defecto, el valor de la propiedad es 0. Este valor hace que el elemento no crezca para ajustarse al espacio disponible. Podríamos decir que es como un «interruptor apagado». Si tenemos en un contenedor un elemento, y establecemos el valor a 1, el elemento pasa a ocupar todo el espacio.

Básicamente, esta propiedad define la capacidad de un elemento para crecer si es necesario. Acepta un valor sin unidades que sirve como una proporción. Indica qué cantidad de espacio disponible dentro del contenedor flexible debe ocupar el elemento.

Si todos los elementotienen un crecimiento flexible establecido en 1, el espacio restante en el contenedor se distribuirá por igual a todos los hijos. Si uno de los hijostiene un valor de 2, el espacio restante ocuparía el doble de espacio que los demás (o lo intentará, al menos).

FlexLayout.Basis

Esta propiedad define el tamaño predeterminado de un elemento antes que se distribuya el espacio restante disponible. Puede ser una proporción, por ejemplo un porcentaje (5%, 25%, etc.). También se pueden utilizar algunas palabras reversadas como Auto.

En combinación con FlexLayout.Grow permite un control bastante completo sobre el tamaño de cada elemento hijo del contenedor.

Conclusiones

No es extraño encontrar la necesidad de gestionar Wrapping de elementos, elementos con diferentes espacios de forma dinámica, etc. La llegada de un nuevo Layout basado en algo conocido como Flexbox y que aporte la posibilidad de gestionar Layouts flexibles de forma sencilla es importante.

FlexLayout

Tienes un ejemplo de FlexLayout disponible en GitHub:

Ver GitHub¿Qué te parece esta nueva opción?. Recuerda, cualquier duda o pregunta es bienvenida en los comentarios de la entrada.

Más información

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *