Xamarin.Forms StackLayout
A StackLayout
organiza as exibições filhas em uma pilha unidimensional, horizontal ou verticalmente. Por padrão, a orientação do StackLayout
é vertical. Além disso, a StackLayout
pode ser usado como um layout pai que contém outros layouts filho.
A classe StackLayout
define as seguintes propriedades:
Orientation
, do tipoStackOrientation
, representa a direção na qual as exibições secundárias são posicionadas. O valor padrão dessa propriedade éVertical
.Spacing
, do tipodouble
, indica a quantidade de espaço entre cada exibição filho. O valor padrão dessa propriedade é seis unidades independentes de dispositivo.
Essas propriedades são apoiadas por BindableProperty
objetos, o que significa que as propriedades podem ser destinos de associações de dados e estilizadas.
A StackLayout
classe deriva da Layout<T>
classe, que define uma Children
propriedade do tipo IList<T>
. A propriedade Children
é o ContentProperty
da classe Layout<T>
e, portanto, não precisa ser definida explicitamente no XAML.
Dica
Para obter o melhor desempenho de layout possível, siga as diretrizes em Otimizar o desempenho do layout.
Orientação vertical
O XAML a seguir mostra como criar um orientado StackLayout
verticalmente que contém diferentes modos de exibição filho:
<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>
Este exemplo cria um contêiner Label
vertical StackLayout
e BoxView
objetos. Por padrão, há seis unidades de espaço independentes de dispositivo entre as exibições filho:
Este é o código C# equivalente:
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 }
}
};
}
}
Observação
O valor da Margin
propriedade representa a distância entre um elemento e seus elementos adjacentes. Para saber mais, confira Margens e preenchimento.
Orientação horizontal
O XAML a seguir mostra como criar um orientado StackLayout
horizontalmente definindo sua Orientation
propriedade como 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 exemplo cria uma horizontal StackLayout
contendo BoxView
objetos, com seis unidades de espaço independentes de dispositivo entre as exibições filho:
Este é o código C# equivalente:
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 }
}
};
}
Espaço entre as visualizações secundárias
O espaçamento entre as exibições secundárias em um StackLayout
pode ser alterado definindo a Spacing
propriedade como um 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>
Este exemplo cria uma vertical StackLayout
contendo Label
e BoxView
objetos que não têm espaçamento entre eles:
Dica
A Spacing
propriedade pode ser definida como valores negativos para fazer com que as exibições secundárias se sobreponham.
Este é o código C# equivalente:
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 }
}
};
}
}
Posição e tamanho das exibições filho
O tamanho e a posição das exibições filhas dentro de um StackLayout
dependem dos valores das exibições HeightRequest
e WidthRequest
propriedades filhas e dos valores de suas HorizontalOptions
propriedades e VerticalOptions
. Em uma vertical StackLayout
, as exibições secundárias se expandem para preencher a largura disponível quando seu tamanho não está definido explicitamente. Da mesma forma, em uma horizontal StackLayout
, as vistas secundárias se expandem para preencher a altura disponível quando seu tamanho não está explicitamente definido.
As HorizontalOptions
propriedades and VerticalOptions
de um StackLayout
, e suas exibições filhas, podem ser definidas como campos do LayoutOptions
struct, que encapsula duas preferências de layout:
- O alinhamento determina a posição e o tamanho de uma vista secundária em seu layout principal.
- A expansão indica se o modo de exibição filho deve usar espaço extra, se estiver disponível.
Dica
Não defina as HorizontalOptions
propriedades e VerticalOptions
de a StackLayout
, a menos que seja necessário. Os valores padrão de LayoutOptions.Fill
e LayoutOptions.FillAndExpand
permitem a melhor otimização de layout. Alterar essas propriedades tem um custo e consome memória, mesmo ao defini-las de volta para os valores padrão.
Alinhamento
O exemplo XAML a seguir define as preferências de alinhamento em cada exibição filho no 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>
Neste exemplo, as Label
preferências de alinhamento são definidas nos objetos para controlar sua posição dentro do StackLayout
. Os Start
campos , Center
, End
, e Fill
são usados para definir o Label
alinhamento dos objetos dentro do pai StackLayout
:
Um StackLayout
respeita somente as preferências de alinhamento em exibições filho que estão na direção oposta à orientação StackLayout
. Portanto, as exibições filho de Label
dentro do StackLayout
orientado verticalmente definem suas propriedades HorizontalOptions
como um dos campos de alinhamento:
Start
, que posiciona oLabel
no lado esquerdo doStackLayout
.Center
, que centraliza oLabel
noStackLayout
.End
, que posiciona oLabel
no lado direito doStackLayout
.Fill
, que garante que oLabel
preencha a largura doStackLayout
.
Este é o código C# equivalente:
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 }
}
};
}
}
Expansão
O exemplo XAML a seguir define preferências de expansão em cada Label
um dos 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>
Neste exemplo, as Label
preferências de expansão são definidas nos objetos para controlar seu tamanho dentro do StackLayout
. Os StartAndExpand
campos , CenterAndExpand
, EndAndExpand
e FillAndExpand
são usados para definir a preferência de alinhamento e se ocuparão Label
mais espaço se disponível no pai StackLayout
:
Um StackLayout
só pode expandir exibições filho na direção de sua orientação. Portanto, o StackLayout
orientado verticalmente pode expandir exibições filho de Label
que definem suas propriedades VerticalOptions
como um dos campos de expansão. Isso significa que, para o alinhamento vertical, cada Label
ocupa a mesma quantidade de espaço dentro do StackLayout
. No entanto, somente o último Label
, que define sua propriedade VerticalOptions
como FillAndExpand
tem um tamanho diferente.
Dica
Ao usar um StackLayout
, certifique-se de que apenas uma exibição secundária esteja definida como LayoutOptions.Expands
. Essa propriedade garante que o filho especificado ocupe o maior espaço que o StackLayout
pode dar a ele e é um desperdício executar esses cálculos mais de uma vez.
Este é o código C# equivalente:
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
Quando todo o espaço em um StackLayout
é usado, as preferências de expansão não têm nenhum efeito.
Para obter mais informações sobre alinhamento e expansão, consulte Opções de layout no Xamarin.Forms.
Objetos StackLayout aninhados
A StackLayout
pode ser usado como um layout pai que contém objetos filho StackLayout
aninhados ou outros layouts filho.
O XAML a seguir mostra um exemplo de aninhamento StackLayout
de objetos:
<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>
Neste exemplo, o pai StackLayout
contém objetos aninhados dentro Frame
de StackLayout
objetos. O pai StackLayout
é orientado verticalmente, enquanto os objetos filho StackLayout
são orientados horizontalmente:
Importante
Quanto mais fundo você aninhar StackLayout
objetos e outros layouts, mais os layouts aninhados afetarão o desempenho. Para obter mais informações, consulte Escolher o layout correto.
Este é o código C# equivalente:
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 }
}
}
},
// ...
}
};
}
}