Elección de un diseño de Xamarin.Forms

Download SampleDescargar el ejemplo

Las clases de diseño de Xamarin.Forms permiten organizar y agrupar los controles de la interfaz de usuario de la aplicación. Elegir una clase de diseño requiere saber cómo coloca el diseño sus elementos secundarios y cómo dicho diseño ajusta el tamaño de sus elementos secundarios. Además, puede ser necesario anidar diseños para crear el diseño deseado.

En la imagen siguiente se muestran diseños típicos que se pueden lograr con las clases de diseño principales de Xamarin.Forms:

The main layout classes in Xamarin.Forms

StackLayout

StackLayout organiza los elementos en una pila unidimensional, ya sea horizontal o verticalmente. La propiedad Orientation especifica la dirección de los elementos y la orientación predeterminada es Vertical. StackLayout suele usarse para organizar una pequeña subsección de la interfaz de usuario en una página.

En el código XAML siguiente se muestra cómo crear un objeto StackLayout vertical que contenga tres objetos Label:

<StackLayout Margin="20,35,20,25">
    <Label Text="The StackLayout has its Margin property set, to control the rendering position of the StackLayout." />
    <Label Text="The Padding property can be set to specify the distance between the StackLayout and its children." />
    <Label Text="The Spacing property can be set to specify the distance between views in the StackLayout." />
</StackLayout>

En StackLayout, si el tamaño de un elemento no se establece explícitamente, se expande para rellenar el ancho disponible, o el alto si la propiedad Orientation está establecida en Horizontal.

StackLayout a menudo se usa como diseño primario, que contiene otros diseños secundarios. Sin embargo, StackLayout no se debe usar para reproducir un diseño Grid mediante una combinación de objetos StackLayout. En el código siguiente se muestra un ejemplo de esta práctica incorrecta:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Details.HomePage"
             Padding="0,20,0,0">
    <StackLayout>
        <StackLayout Orientation="Horizontal">
            <Label Text="Name:" />
            <Entry Placeholder="Enter your name" />
        </StackLayout>
        <StackLayout Orientation="Horizontal">
            <Label Text="Age:" />
            <Entry Placeholder="Enter your age" />
        </StackLayout>
        <StackLayout Orientation="Horizontal">
            <Label Text="Occupation:" />
            <Entry Placeholder="Enter your occupation" />
        </StackLayout>
        <StackLayout Orientation="Horizontal">
            <Label Text="Address:" />
            <Entry Placeholder="Enter your address" />
        </StackLayout>
    </StackLayout>
</ContentPage>

Es una pérdida de tiempo porque se realizan cálculos de diseño innecesarios. En su lugar, el diseño deseado se puede lograr mejor mediante Grid.

Sugerencia

Al usar un elemento StackLayout, asegúrese de que solo un elemento secundario está establecido en LayoutOptions.Expands. Esta propiedad garantiza que el elemento secundario especificado ocupa el mayor espacio que el StackLayout puede asignarle y es poco rentable realizar estos cálculos más de una vez.

Para más información, consulte StackLayout de Xamarin.Forms.

Grid

Grid se usa para mostrar elementos en filas y columnas, que pueden tener tamaños proporcionales o absolutos. Las filas y columnas de una cuadrícula se especifican con las propiedades RowDefinitions y ColumnDefinitions.

Para colocar elementos en celdas Grid específicas, usa las propiedades adjuntas Grid.Column y Grid.Row. Para que los elementos abarquen varias filas y columnas, usa las propiedades adjuntas Grid.RowSpan y Grid.ColumnSpan.

Nota:

Un diseño Grid no debe confundirse con las tablas y no está pensado para presentar datos tabulares. A diferencia de las tablas HTML, una Grid está pensada para diseñar contenido. Para mostrar datos tabulares, considere el uso de un elemento ListView, CollectionView o TableView.

En el código XAML siguiente se muestra cómo crear Grid con dos filas y dos columnas:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="50" />
        <RowDefinition Height="50" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>    
    <Label Text="Column 0, Row 0"
           WidthRequest="200" />
    <Label Grid.Column="1"
           Text="Column 1, Row 0" />
    <Label Grid.Row="1"
           Text="Column 0, Row 1" />
    <Label Grid.Column="1"
           Grid.Row="1"
           Text="Column 1, Row 1" />
</Grid>

En este ejemplo, el ajuste de tamaño funciona de la siguiente manera:

  • Cada fila tiene un alto explícito de 50 unidades independientes del dispositivo.
  • El ancho de la primera columna se establece en Auto y, por tanto, es tan ancho como sea necesario para sus elementos secundarios. En este caso, es de 200 unidades independientes del dispositivo de ancho para acomodar el ancho del primer Label.

El espacio se puede distribuir dentro de una columna o fila mediante el ajuste de tamaño automático, lo que permite que el tamaño de las columnas y de las filas se ajusten a su contenido. Esto se logra estableciendo el alto de RowDefinition o el ancho de ColumnDefinition en Auto. El ajuste de tamaño proporcional también se puede usar para distribuir el espacio disponible entre las filas y columnas de la cuadrícula en proporciones ponderadas. Esto se logra estableciendo el alto de RowDefinition o el ancho de ColumnDefinition en un valor que usa el operador *.

Precaución

Intenta asegurarte de establecer en tamaño Auto el menor número posible de filas y columnas. Cada fila o columna de tamaño automático hará que el motor de diseño tenga que realizar cálculos de diseño adicionales. En su lugar, use filas y columnas de tamaño fijo si es posible. Como alternativa, establece las filas y columnas para que ocupen una cantidad proporcional de espacio con el valor de enumeración GridUnitType.Star.

Para más información, consulte Cuadrícula de Xamarin.Forms.

FlexLayout

FlexLayout es similar a un elemento StackLayout en el sentido que muestra elementos secundarios horizontal o verticalmente en una pila. Sin embargo, un elemento FlexLayout también puede encapsular sus elementos secundarios si hay demasiados para caber en una sola fila o columna, y también permite un control más granular del tamaño, la orientación y la alineación de sus elementos secundarios.

En el código XAML siguiente se muestra cómo crear un objeto FlexLayout que muestra sus vistas en una sola columna:

<FlexLayout Direction="Column"
            AlignItems="Center"
            JustifyContent="SpaceEvenly">
    <Label Text="FlexLayout in Action" />
    <Button Text="Button" />
    <Label Text="Another Label" />
</FlexLayout>

En este ejemplo, el diseño funciona de la siguiente manera:

  • La propiedad Direction se establece en Column, lo que hace que los elementos secundarios del objeto FlexLayout se organicen en una sola columna de elementos.
  • La propiedad AlignItems se establece en Center, lo que hace que cada elemento se centre horizontalmente.
  • La propiedad JustifyContent se establece en SpaceEvenly, que asigna todo el espacio vertical restante de forma equitativa entre todos los elementos, y por encima del primer elemento, y por debajo del último elemento.

Para más información, consulte FlexLayout de Xamarin.Forms.

RelativeLayout

Un elemento RelativeLayout se usa para colocar y ajustar el tamaño de los elementos en relación con las propiedades de los elementos del diseño o del mismo nivel. De forma predeterminada, un elemento se coloca en la esquina superior izquierda del diseño. Un elemento RelativeLayout se puede usar para crear interfaces de usuario que se escalan proporcionalmente entre tamaños de dispositivo.

Dentro de un elemento RelativeLayout, las posiciones y los tamaños se especifican como restricciones. Las restricciones tienen las propiedades Factor y Constant, que se pueden usar para definir posiciones y tamaños como múltiplos (o fracciones) de propiedades de otros objetos, más una constante. Además, las constantes pueden ser negativas.

Nota:

Un elemento RelativeLayout admite el posicionamiento de elementos fuera de sus propios límites.

En el código XAML siguiente se muestra cómo organizar elementos en un elemento RelativeLayout:

<RelativeLayout>
    <BoxView Color="Blue"
             HeightRequest="50"
             WidthRequest="50"
             RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0}"
             RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0}" />
    <BoxView Color="Red"
             HeightRequest="50"
             WidthRequest="50"
             RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=.85}"
             RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0}" />
    <BoxView x:Name="pole"
             Color="Gray"
             WidthRequest="15"
             RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=.75}"
             RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=.45}"
             RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=.25}" />
    <BoxView Color="Green"
             RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=.10, Constant=10}"
             RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=.2, Constant=20}"
             RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToView, ElementName=pole, Property=X, Constant=15}"
             RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToView, ElementName=pole, Property=Y, Constant=0}" />
</RelativeLayout>

En este ejemplo, el diseño funciona de la siguiente manera:

  • El elemento BoxView azul recibe un tamaño explícito de 50 x 50 unidades independientes del dispositivo. Se coloca en la esquina superior izquierda del diseño, que es la posición predeterminada.
  • El elemento BoxView rojo recibe un tamaño explícito de 50 x 50 unidades independientes del dispositivo. Se coloca en la esquina superior derecha del diseño.
  • El elemento BoxView gris tiene un ancho explícito de 15 unidades independientes del dispositivo y su alto se establece en un 75 % del alto de su elemento primario.
  • El elemento BoxView verde no tiene un tamaño explícito. Su posición se establece en relación con el elemento BoxView llamado pole.

Advertencia

Evite el uso de un RelativeLayout siempre que sea posible. Como resultado, la CPU tendrá que realizar mucho más trabajo.

Para más información, consulte RelativeLayout de Xamarin.Forms.

AbsoluteLayout

AbsoluteLayout se usa para colocar y ajustar el tamaño de los elementos mediante valores explícitos o valores relativos al tamaño del diseño. La posición se especifica en la esquina superior izquierda del elemento secundario en relación con la esquina superior izquierda de AbsoluteLayout.

AbsoluteLayout debe considerarse como un sistema de diseño de ámbito especial que solo se usará cuando el programador pueda aplicar un tamaño en los elementos secundarios o cuando el tamaño del elemento no afecte a la posición de otros elementos secundarios. Un uso estándar de este diseño es crear una superposición, que cubre la página con otros controles, quizás para impedir que el usuario interactúe con los controles normales de la página.

Importante

Las propiedades HorizontalOptions y VerticalOptions no tienen ningún efecto en los elementos secundarios de un AbsoluteLayout.

Dentro de AbsoluteLayout la propiedad adjunta AbsoluteLayout.LayoutBounds se usa para especificar la posición horizontal, posición vertical, anchura y altura de un elemento. Además, la propiedad adjunta AbsoluteLayout.LayoutFlags especifica cómo se interpretarán los límites del diseño.

En el código XAML siguiente se muestra cómo organizar elementos en AbsoluteLayout:

<AbsoluteLayout Margin="40">
    <BoxView Color="Red"
             AbsoluteLayout.LayoutFlags="PositionProportional"
             AbsoluteLayout.LayoutBounds="0.5, 0, 100, 100"
             Rotation="30" />
    <BoxView Color="Green"
             AbsoluteLayout.LayoutFlags="PositionProportional"
             AbsoluteLayout.LayoutBounds="0.5, 0, 100, 100"
             Rotation="60" />
    <BoxView Color="Blue"
             AbsoluteLayout.LayoutFlags="PositionProportional"
             AbsoluteLayout.LayoutBounds="0.5, 0, 100, 100" />
</AbsoluteLayout>

En este ejemplo, el diseño funciona de la siguiente manera:

  • A cada BoxView se le asigna un tamaño explícito de 100x100 y se muestra en la misma posición, centrado horizontalmente.
  • El elemento BoxView rojo gira 30 grados y el elemento BoxView verde gira 60 grados.
  • En cada BoxView, la propiedad adjunta AbsoluteLayout.LayoutFlags se establece PositionProportional, lo que indica que la posición es proporcional al espacio restante después de que se tenga en cuenta la anchura y altura.

Precaución

Evita usar la propiedad AbsoluteLayout.AutoSize siempre que sea posible, ya que esto hará que el motor de diseño realice cálculos de diseño adicionales.

Para más información, consulte AbsoluteLayout de Xamarin.Forms.

Transparencia de la entrada

Cada elemento visual tiene una propiedad InputTransparent que se usa para definir si el elemento recibe la entrada. Su valor predeterminado es false, lo que garantiza que el elemento recibe la entrada.

Cuando esta propiedad se establece en una clase de diseño, su valor se transfiere a elementos secundarios. Por lo tanto, establecer la propiedad InputTransparent en true en una clase de diseño dará lugar a que todos los elementos del diseño no reciban la entrada.

Rendimiento del diseño

Para obtener el mejor rendimiento posible del diseño, siga las instrucciones de Optimización del rendimiento del diseño.

Además, el rendimiento de la representación de páginas también se puede mejorar mediante la compresión del diseño, que quita los diseños especificados del árbol visual. Para más información, consulte Compresión del diseño.