Xamarin.Forms StackLayout

Xamarin.Forms StackLayout

Un StackLayout organiza las vistas secundarias en una pila unidimensional, ya sea horizontal o verticalmente. De forma predeterminada, las vistas StackLayout están orientadas verticalmente. Además, se puede usar una StackLayout como diseño primario que contiene otros diseños secundarios.

La clase StackLayout define las propiedades siguientes:

  • Orientation, de tipo StackOrientation, representa la dirección en la que se colocan las vistas secundarias. El valor predeterminado de esta propiedad es Vertical.
  • Spacing, de tipo double, indica la cantidad de espacio entre cada vista secundaria. El valor predeterminado de esta propiedad es seis unidades independientes del dispositivo.

Todas estas propiedades están respaldadas por objetos BindableProperty, lo que significa que las propiedades pueden ser destinos de los enlaces de datos, y se les puede aplicar estilos.

La clase StackLayout deriva de la clase Layout<T>, que define una propiedad Children de tipo IList<T>. La propiedad Children es ContentProperty de la clase Layout<T> y, por tanto, no es necesario establecerla explícitamente desde XAML.

Sugerencia

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

Orientación vertical

En el código XAML siguiente se muestra cómo crear un elemento StackLayout orientado verticalmente que contiene diferentes vistas secundarias:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="StackLayoutDemos.Views.VerticalStackLayoutPage"
             Title="Vertical StackLayout demo">
    <StackLayout Margin="20">
        <Label Text="Primary colors" />
        <BoxView Color="Red" />
        <BoxView Color="Yellow" />
        <BoxView Color="Blue" />
        <Label Text="Secondary colors" />
        <BoxView Color="Green" />
        <BoxView Color="Orange" />
        <BoxView Color="Purple" />
    </StackLayout>
</ContentPage>

En este ejemplo se crea una instancia vertical StackLayout que contiene objetos Label y BoxView. De forma predeterminada, hay seis unidades de espacio independientes del dispositivo entre las vistas secundarias:

Captura de pantalla de StackLayout orientado verticalmente

El código de C# equivalente es el siguiente:

public class VerticalStackLayoutPageCS : ContentPage
{
    public VerticalStackLayoutPageCS()
    {
        Title = "Vertical StackLayout demo";
        Content = new StackLayout
        {
            Margin = new Thickness(20),
            Children =
            {
                new Label { Text = "Primary colors" },
                new BoxView { Color = Color.Red },
                new BoxView { Color = Color.Yellow },
                new BoxView { Color = Color.Blue },
                new Label { Text = "Secondary colors" },
                new BoxView { Color = Color.Green },
                new BoxView { Color = Color.Orange },
                new BoxView { Color = Color.Purple }
            }
        };
    }
}

Nota:

El valor de la propiedad Margin representa la distancia entre un elemento y sus elementos adyacentes. Para obtener más información, vea Márgenes y relleno.

Orientación horizontal

En el código XAML siguiente se muestra cómo crear un objeto orientado horizontalmente StackLayout estableciendo su propiedad Orientation en Horizontal:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="StackLayoutDemos.Views.HorizontalStackLayoutPage"
             Title="Horizontal StackLayout demo">
    <StackLayout Margin="20"
                 Orientation="Horizontal"
                 HorizontalOptions="Center">
        <BoxView Color="Red" />
        <BoxView Color="Yellow" />
        <BoxView Color="Blue" />
        <BoxView Color="Green" />
        <BoxView Color="Orange" />
        <BoxView Color="Purple" />
    </StackLayout>
</ContentPage>

Este ejemplo crea un StackLayout horizontal que contiene objetos BoxView, con seis unidades de espacio independientes del dispositivo entre las vistas secundarias:

Captura de pantalla de StackLayout orientado horizontalmente

El código de C# equivalente es el siguiente:

public HorizontalStackLayoutPageCS()
{
    Title = "Horizontal StackLayout demo";
    Content = new StackLayout
    {
        Margin = new Thickness(20),
        Orientation = StackOrientation.Horizontal,
        HorizontalOptions = LayoutOptions.Center,
        Children =
        {
            new BoxView { Color = Color.Red },
            new BoxView { Color = Color.Yellow },
            new BoxView { Color = Color.Blue },
            new BoxView { Color = Color.Green },
            new BoxView { Color = Color.Orange },
            new BoxView { Color = Color.Purple }
        }
    };
}

Espacio entre vistas secundarias

El espaciado entre las vistas secundarias de un StackLayout objeto se puede cambiar estableciendo la Spacing propiedad en un double valor:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="StackLayoutDemos.Views.StackLayoutSpacingPage"
             Title="StackLayout Spacing demo">
    <StackLayout Margin="20"
                 Spacing="0">
        <Label Text="Primary colors" />
        <BoxView Color="Red" />
        <BoxView Color="Yellow" />
        <BoxView Color="Blue" />
        <Label Text="Secondary colors" />
        <BoxView Color="Green" />
        <BoxView Color="Orange" />
        <BoxView Color="Purple" />
    </StackLayout>
</ContentPage>

En este ejemplo se crea un StackLayout vertical que contiene objetos Label y BoxView que no tienen ningún espaciado entre ellos:

Captura de pantalla de StackLayout sin espaciado

Sugerencia

La propiedad Spacing se puede establecer en valores negativos para que las vistas secundarias se superpongan.

El código de C# equivalente es el siguiente:

public class StackLayoutSpacingPageCS : ContentPage
{
    public StackLayoutSpacingPageCS()
    {
        Title = "StackLayout Spacing demo";
        Content = new StackLayout
        {
            Margin = new Thickness(20),
            Spacing = 0,
            Children =
            {
                new Label { Text = "Primary colors" },
                new BoxView { Color = Color.Red },
                new BoxView { Color = Color.Yellow },
                new BoxView { Color = Color.Blue },
                new Label { Text = "Secondary colors" },
                new BoxView { Color = Color.Green },
                new BoxView { Color = Color.Orange },
                new BoxView { Color = Color.Purple }
            }
        };
    }
}

Posición y tamaño de las vistas secundarias

El tamaño y la posición de las vistas secundarias dentro de StackLayout dependen de los valores de las propiedades HeightRequest y WidthRequest de las vistas secundarias, y de los valores de sus propiedades HorizontalOptions y VerticalOptions. En un StackLayout vertical, las vistas secundarias se expanden para rellenar el ancho disponible cuando su tamaño no se establece explícitamente. Del mismo modo, en un StackLayout horizontal las vistas secundarias se expanden para rellenar el alto disponible cuando su tamaño no se establece explícitamente.

Las propiedades HorizontalOptions y VerticalOptions de un StackLayout, y sus vistas secundarias, se pueden establecer en campos de la estructura LayoutOptions, que encapsula dos preferencias de diseño:

  • Alineación determina la posición y el tamaño de una vista secundaria dentro de su diseño primario.
  • Expansión indica si la vista secundaria debe usar espacio adicional, si está disponible.

Sugerencia

No establezca las propiedades HorizontalOptions y VerticalOptions de un StackLayout a menos que haga falta. Los valores predeterminados de LayoutOptions.Fill y LayoutOptions.FillAndExpand permiten la optimización de diseño óptima. El cambio de estas propiedades tiene un costo y consume memoria, incluso al volver a establecerlas en los valores predeterminados.

Alineación

En el ejemplo XAML siguiente se establecen las preferencias de alineación en cada vista secundaria de StackLayout:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="StackLayoutDemos.Views.AlignmentPage"
             Title="Alignment demo">
    <StackLayout Margin="20">
        <Label Text="Start"
               BackgroundColor="Gray"
               HorizontalOptions="Start" />
        <Label Text="Center"
               BackgroundColor="Gray"
               HorizontalOptions="Center" />
        <Label Text="End"
               BackgroundColor="Gray"
               HorizontalOptions="End" />
        <Label Text="Fill"
               BackgroundColor="Gray"
               HorizontalOptions="Fill" />
    </StackLayout>
</ContentPage>

En este ejemplo, las preferencias de alineación se establecen en los objetos Label para controlar su posición dentro de StackLayout. Los campos Start, Center, End y Fill se usan para definir la alineación de los objetos de Label en StackLayout primario.

Captura de pantalla de StackLayout con opciones de alineación establecidas

Un elemento StackLayout solo respeta las preferencias de alineación de las vistas secundarias que tienen la dirección opuesta a la orientación del StackLayout. Por lo tanto, las vistas secundarias de Label dentro del StackLayout con orientación vertical establecen sus propiedades HorizontalOptions en uno de los campos de alineación siguientes:

El código de C# equivalente es el siguiente:

public class AlignmentPageCS : ContentPage
{
    public AlignmentPageCS()
    {
        Title = "Alignment demo";
        Content = new StackLayout
        {
            Margin = new Thickness(20),
            Children =
            {
                new Label { Text = "Start", BackgroundColor = Color.Gray, HorizontalOptions = LayoutOptions.Start },
                new Label { Text = "Center", BackgroundColor = Color.Gray, HorizontalOptions = LayoutOptions.Center },
                new Label { Text = "End", BackgroundColor = Color.Gray, HorizontalOptions = LayoutOptions.End },
                new Label { Text = "Fill", BackgroundColor = Color.Gray, HorizontalOptions = LayoutOptions.Fill }
            }
        };
    }
}

Expansión

En el siguiente ejemplo XAML se establecen preferencias de expansión en cada Label del StackLayout:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="StackLayoutDemos.Views.ExpansionPage"
             Title="Expansion demo">
    <StackLayout Margin="20">
        <BoxView BackgroundColor="Red"
                 HeightRequest="1" />
        <Label Text="Start"
               BackgroundColor="Gray"
               VerticalOptions="StartAndExpand" />
        <BoxView BackgroundColor="Red"
                 HeightRequest="1" />
        <Label Text="Center"
               BackgroundColor="Gray"
               VerticalOptions="CenterAndExpand" />
        <BoxView BackgroundColor="Red"
                 HeightRequest="1" />
        <Label Text="End"
               BackgroundColor="Gray"
               VerticalOptions="EndAndExpand" />
        <BoxView BackgroundColor="Red"
                 HeightRequest="1" />
        <Label Text="Fill"
               BackgroundColor="Gray"
               VerticalOptions="FillAndExpand" />
        <BoxView BackgroundColor="Red"
                 HeightRequest="1" />
    </StackLayout>
</ContentPage>

En este ejemplo, las preferencias de expansión se establecen en los objetos Label para controlar su tamaño dentro del StackLayout. Los campos StartAndExpand, CenterAndExpand, EndAndExpand y FillAndExpand se usan para definir la preferencia de alineación y si el Label ocupará más espacio si está disponible en el StackLayout primario:

Captura de pantalla de StackLayout con opciones de expansión establecidas

Un elemento StackLayout solo puede expandir las vistas secundarias en la dirección de su orientación. Por lo tanto, un StackLayout con orientación vertical puede expandir las vistas secundarias de Label que establecen sus propiedades VerticalOptions en uno de los campos de alineación. Esto significa que, para la alineación vertical, cada Label ocupa la misma cantidad de espacio en el StackLayout. Aun así, solo el último elemento Label, que establece su propiedad VerticalOptions en FillAndExpand, tiene un tamaño diferente.

Sugerencia

Al usar un StackLayout, asegúrese de que solo una vista secundaria esté establecida 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.

El código de C# equivalente es el siguiente:

public ExpansionPageCS()
{
    Title = "Expansion demo";
    Content = new StackLayout
    {
        Margin = new Thickness(20),
        Children =
        {
            new BoxView { BackgroundColor = Color.Red, HeightRequest = 1 },
            new Label { Text = "StartAndExpand", BackgroundColor = Color.Gray, VerticalOptions = LayoutOptions.StartAndExpand },
            new BoxView { BackgroundColor = Color.Red, HeightRequest = 1 },
            new Label { Text = "CenterAndExpand", BackgroundColor = Color.Gray, VerticalOptions = LayoutOptions.CenterAndExpand },
            new BoxView { BackgroundColor = Color.Red, HeightRequest = 1 },
            new Label { Text = "EndAndExpand", BackgroundColor = Color.Gray, VerticalOptions = LayoutOptions.EndAndExpand },
            new BoxView { BackgroundColor = Color.Red, HeightRequest = 1 },
            new Label { Text = "FillAndExpand", BackgroundColor = Color.Gray, VerticalOptions = LayoutOptions.FillAndExpand },
            new BoxView { BackgroundColor = Color.Red, HeightRequest = 1 }
        }
    };
}

Importante

Cuando se usa todo el espacio de un elemento StackLayout, las preferencias de expansión no tienen ningún efecto.

Para obtener más información sobre la alineación y la expansión, consulte Opciones de diseño en Xamarin.Forms.

Objetos StackLayout anidados

StackLayout Se puede usar como diseño primario que contiene objetos secundarios anidados StackLayout u otros diseños secundarios.

En el siguiente ejemplo de XAML se muestra un ejemplo de anidación de objetos StackLayout:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="StackLayoutDemos.Views.CombinedStackLayoutPage"
             Title="Combined StackLayouts demo">
    <StackLayout Margin="20">
        ...
        <Frame BorderColor="Black"
               Padding="5">
            <StackLayout Orientation="Horizontal"
                         Spacing="15">
                <BoxView Color="Red" />
                <Label Text="Red"
                       FontSize="Large"
                       VerticalOptions="Center" />
            </StackLayout>
        </Frame>
        <Frame BorderColor="Black"
               Padding="5">
            <StackLayout Orientation="Horizontal"
                         Spacing="15">
                <BoxView Color="Yellow" />
                <Label Text="Yellow"
                       FontSize="Large"
                       VerticalOptions="Center" />
            </StackLayout>
        </Frame>
        <Frame BorderColor="Black"
               Padding="5">
            <StackLayout Orientation="Horizontal"
                         Spacing="15">
                <BoxView Color="Blue" />
                <Label Text="Blue"
                       FontSize="Large"
                       VerticalOptions="Center" />
            </StackLayout>
        </Frame>
        ...
    </StackLayout>
</ContentPage>

En este ejemplo, el elemento primario StackLayout contiene objetos anidados StackLayout dentro de objetosFrame. El elemento primario StackLayout está orientado verticalmente, mientras que los objetos secundarios StackLayout están orientados horizontalmente:

Captura de pantalla de objetos StackLayout anidados

Importante

Cuanto más profundo anides StackLayout los objetos y otros diseños, más afectarán al rendimiento. Para obtener más información, consulta Elegir el diseño correcto.

El código de C# equivalente es el siguiente:

public class CombinedStackLayoutPageCS : ContentPage
{
    public CombinedStackLayoutPageCS()
    {
        Title = "Combined StackLayouts demo";
        Content = new StackLayout
        {
            Margin = new Thickness(20),
            Children =
            {
                new Label { Text = "Primary colors" },
                new Frame
                {
                    BorderColor = Color.Black,
                    Padding = new Thickness(5),
                    Content = new StackLayout
                    {
                        Orientation = StackOrientation.Horizontal,
                        Spacing = 15,
                        Children =
                        {
                            new BoxView { Color = Color.Red },
                            new Label { Text = "Red", FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)), VerticalOptions = LayoutOptions.Center }
                        }
                    }
                },
                new Frame
                {
                    BorderColor = Color.Black,
                    Padding = new Thickness(5),
                    Content = new StackLayout
                    {
                        Orientation = StackOrientation.Horizontal,
                        Spacing = 15,
                        Children =
                        {
                            new BoxView { Color = Color.Yellow },
                            new Label { Text = "Yellow", FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)), VerticalOptions = LayoutOptions.Center }
                        }
                    }
                },
                new Frame
                {
                    BorderColor = Color.Black,
                    Padding = new Thickness(5),
                    Content = new StackLayout
                    {
                        Orientation = StackOrientation.Horizontal,
                        Spacing = 15,
                        Children =
                        {
                            new BoxView { Color = Color.Blue },
                            new Label { Text = "Blue", FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)), VerticalOptions = LayoutOptions.Center }
                        }
                    }
                },
                // ...
            }
        };
    }
}