Xampane, nuevos Layouts para Xamarin.Forms

Layouts en Xamarin.Forms

A la hora de organizar y posicionar los elementos visuales que componen la interfaz de usuario en Xamarin.Forms, hacemos uso de Layouts.

Layouts

Tenemos una enorme variedad de Layouts en Xamarin.Forms. Podemos posicionar de forma absoluta; de forma relativa; apilar elementos; etc. Con un uso correcto de los mismo se pueden cubrir la mayoría de necesidades pero…¿qué ocurre cuando no nos encaja al 100%?.

Por ejemplo, si necesitamos posicionar botones circulares alrededor de una imagen circular (perfil de usuario), ¿que Layout nos encaja?. Podemos conseguir nuestro objetivo con los Layouts disponibles pero probablemente con ajustes específicos para posicionar cada elemento. ¿Podemos conseguirlo de forma más sencilla?.

Creando Layouts

Un Layout es una clase que deriva de View. Podemos crear Layouts personalizados en Xamarin.Forms con clases que hereden de Layout<T>.

public class MyCustomayout : Layout<View>
{

}

Antes de continuar, vamos a repasar algunos conceptos básicos.

Cada VisualElement define un método Measure que se encarga de calcular el tamaño del elemento, y un método Layout que especifica el área rectangular donde se va a representar. Cuando se inicia una aplicación Xamarin.Forms y se muestra la primera página,  se lanza  un “ciclo de Layout” que consta de varias llamadas Measure primero y, a continuación, se lanza Layout.

Cada clase que derive de Layout o Layout<View> debe sobrecargar el método OnMeasure, que es donde el Layout determina el tamaño que debe tener realizando llamadas al método Measure de sus elementos hijos. Además, cada clase Xamarin.Forms que contenta Content o Children (como es el caso del Layout) cuenta con un método LayoutChildren que es donde se posicionan y ajustan los elementos hijos.

Ten en cuenta que, normalmente un cambio en el tamaño de un elemento afecta a cómo el Layout organiza a sus elementos secundarios. Por lo tanto, un cambio en el tamaño de un elemento iniciará un “ciclo de Layout” para el Layout y se llamarán a los métodos OnMeasure y LayoutChildren. A este proceso, se le llama invalidación. Por ejemplo, si un Label dentro del Layout pasa de tener fuente 12 a 24, si tamaño deja de ser correcto. El elemento pasaría a estar marcado como no válido y se ejecutaría el método InvalidateMeasure.

public class MyCustomLayout : Layout<View>
{
     protected override SizeRequest OnMeasure(double widthConstraint, double heightConstraint)
     {

     }
 
     protected override void LayoutChildren(double x, double y, double width, double height)
     {

     }
}

Xampane

Xampage es una librería que añade nuevos Layouts para Xamarin.Forms. Actualmente la librería cuenta con los siguientes Layouts:

  • CircularLayout
  • DockLayout
  • HexLayout
  • UniformGrid
  • WrapLayout

La librería esta disponible en NuGet. Para instalar la misma basta con añadir el paquete:

Install-Package XamPane -Version 1.0.0

CircularLayout

CircularLayout es un Layout que organiza a sus elementos hijos en una disposición circular. Tiene algunas propiedades útiles para permitir cierta personalización como la propiedad Orientation (en sentido horario o antihorario).

<xampane:CircularLayout
    Orientation="Clockwise">
    <BoxView Color="Black" CornerRadius="6" WidthRequest="6" HeightRequest="6" />       
    <BoxView Color="Red" CornerRadius="12" WidthRequest="12" HeightRequest="12" xampane:CircularLayout.Angle="0" xampane:CircularLayout.Radius="120" />
    <BoxView Color="Green" CornerRadius="12" WidthRequest="12" HeightRequest="12" xampane:CircularLayout.Angle="10" xampane:CircularLayout.Radius="120" />
    <BoxView Color="Blue" CornerRadius="12" WidthRequest="12" HeightRequest="12" xampane:CircularLayout.Angle="20" xampane:CircularLayout.Radius="120" />
    <BoxView Color="Yellow" CornerRadius="12" WidthRequest="12" HeightRequest="12" xampane:CircularLayout.Angle="30" xampane:CircularLayout.Radius="120" />
    <Label Text="1" xampane:CircularLayout.Angle="30" xampane:CircularLayout.Radius="90" />
    <Label Text="2" xampane:CircularLayout.Angle="60" xampane:CircularLayout.Radius="90" />
    <Label Text="3" xampane:CircularLayout.Angle="90" xampane:CircularLayout.Radius="90" />
    <Label Text="4" xampane:CircularLayout.Angle="120" xampane:CircularLayout.Radius="90" />
    <Label Text="5" xampane:CircularLayout.Angle="150" xampane:CircularLayout.Radius="90" />
    <Label Text="6" xampane:CircularLayout.Angle="180" xampane:CircularLayout.Radius="90" />
    <Label Text="7" xampane:CircularLayout.Angle="210" xampane:CircularLayout.Radius="90" />
    <Label Text="8" xampane:CircularLayout.Angle="240" xampane:CircularLayout.Radius="90" />
    <Label Text="9" xampane:CircularLayout.Angle="270" xampane:CircularLayout.Radius="90" />
    <Label Text="10" xampane:CircularLayout.Angle="300" xampane:CircularLayout.Radius="90" />
    <Label Text="11" xampane:CircularLayout.Angle="330" xampane:CircularLayout.Radius="90" />
    <Label Text="12" xampane:CircularLayout.Angle="360" xampane:CircularLayout.Radius="90" />
</xampane:CircularLayout>

El resultado:

CircularLayout

Las propiedades del Layout que nos permiten organizar los elementos son:

  • Orientation: Permite organizar los elementos en el sentido de las agujas del reloj (Clockwise) o en sentido contrario (CounterClockwise).
  • Ange: Valor numérico entre 0 y 360. Permite posicionar cualquier elemento en un angulo concreto del círculo.
  • Radius: La distancia con respecto el centro.

DockLayout

DockLayout permite acoplar los elementos hijos a la parte superior, inferior, izquierda o derecha. Por defecto, el último control, si no se le da una posición de acoplamiento específica, llenará el espacio restante. Se puede conseguir lo mismo con el Grid, pero para las situaciones más simples, DockLayout será más fácil de usar. 

<xampane:DockLayout
    LastChildFill="False">
    <Button xampane:DockLayout.Dock="Top" Text="Top" HeightRequest="50"/>
    <Button xampane:DockLayout.Dock="Bottom" Text="Bottom" HeightRequest="50"/>
    <Button xampane:DockLayout.Dock="Left" Text="Left" WidthRequest="60"/>
    <Button xampane:DockLayout.Dock="Left" Text="Left" WidthRequest="60"/>
    <Button xampane:DockLayout.Dock="Right" Text="Right" WidthRequest="80"/>
    <Button xampane:DockLayout.Dock="Right" Text="Right" WidthRequest="80"/>
</xampane:DockLayout>

El resultado:

DockLayout

Contamos con la propiedad adjunta Dock. Esta propiedad permite acoplar cualquier elemento hijo a la parte superior, inferior, izquierda o derecha. Por otro lado, la propiedad LastChildFill (bool) permite indicar si el último elemento hijo ocupa todo el espacio restante disponible o no.

HexLayout

Organiza los elementos siguiento un patrón de panel de abejas.

<xampane:HexLayout
    RowCount="3"
    ColumnCount="3"
    Orientation="Vertical">
    <polygon:PolygonFrame Grid.Row="0" Grid.Column="1" OffsetAngle="90" BackgroundColor="Red"/>
    <polygon:PolygonFrame Grid.Row="0" Grid.Column="2" OffsetAngle="90" BackgroundColor="Green"/>
    <polygon:PolygonFrame Grid.Row="1" Grid.Column="0" OffsetAngle="90" BackgroundColor="Blue"/>
    <polygon:PolygonFrame Grid.Row="1" Grid.Column="1" OffsetAngle="90" BackgroundColor="Yellow"/>
    <polygon:PolygonFrame Grid.Row="1" Grid.Column="2" OffsetAngle="90" BackgroundColor="Orange"/>
    <polygon:PolygonFrame Grid.Row="2" Grid.Column="1" OffsetAngle="90" BackgroundColor="Purple"/>
    <polygon:PolygonFrame Grid.Row="2" Grid.Column="2" OffsetAngle="90" BackgroundColor="Pink"/>
</xampane:HexLayout>

Veamos como organiza los elementos:

HexLayout

El panel permite definir la orientación con la propiedad Orientation (horizontal o vertical). Para organizar los elementos usamos las propiedades adjuntas Grid y Row.

UniformGrid

UniformGrid (es el Layout más simple incluido en la librería) es como un Grid, es decir, permite definir múltiples filas y columnas, pero con una diferencia importante: todas las filas y columnas tendrán el mismo tamaño.

<xampane:UniformGrid>
    <BoxView Color="Red" />
    <BoxView Color="Yellow" />
    <BoxView Color="Orange" />
    <BoxView Color="Purple" />
    <BoxView Color="Blue" />
    <BoxView Color="Green" />
    <BoxView Color="LightGreen" />
    <BoxView Color="Gray" />
    <BoxView Color="Pink" />
</xampane:UniformGrid>

UniformGrid

WrapLayout

El WrapLayout colocará cada uno de sus elementos hijos al lado del otro, horizontalmente (de forma predeterminada) o verticalmente, hasta que no haya más espacio, momento en el que pasara  la siguiente línea y continuará. 

<xampane:WrapLayout 
    Orientation="Vertical"
    Spacing="6"
    HorizontalOptions="Center">
    <BoxView Color="Red" />
    <BoxView Color="Yellow" />
    <BoxView Color="Orange" />
    <BoxView Color="Purple" />
    <BoxView Color="Blue" />
    <BoxView Color="Green" />
    <BoxView Color="LightGreen" />
    <BoxView Color="Gray" />
    <BoxView Color="Pink" />
</xampane:WrapLayout>

El resultado:

WrapLayout

La propiedad fundamental del control es Orientation con las opciones Vertical u Horizontal.

Puedes encontrar el código de la librería disponible en GitHub:

Ver GitHub

¿Qué te parece la librería?, ¿qué Layout te resulta más útil?. Recuerda, puedes dejar cualquier duda o comentario!.

Más información

2 pensamientos en “Xampane, nuevos Layouts para Xamarin.Forms

  1. Warp layout hay la tira desde hace catapún… Me ha aliviado un montón verlo incluido aquí: Con uno bien hecho incluido en una librería con cabeza me puedo olvidar de los varios NuGets a medio hacer que he venido mal usando (aunque muy agradecido a sus autores, claro) hasta la fecha. ¡Gracias!

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s