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 tipoStackOrientation
, representa la dirección en la que se colocan las vistas secundarias. El valor predeterminado de esta propiedad esVertical
.Spacing
, de tipodouble
, 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:
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:
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:
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.
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:
Start
, que colocaLabel
en el lado izquierdo delStackLayout
.Center
, que centraLabel
en elStackLayout
.End
, que colocaLabel
en el lado derecho delStackLayout
.Fill
, que garantiza queLabel
llena el ancho delStackLayout
.
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:
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:
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 }
}
}
},
// ...
}
};
}
}