Xamarin.Forms StackLayout
A StackLayout
organiza exibições filho em uma pilha unidimensional, horizontal ou verticalmente. Por padrão, a orientação do StackLayout
é vertical. Além disso, um 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 visões filho são posicionadas. O valor padrão dessa propriedade éVertical
.Spacing
, do tipodouble
, indica a quantidade de espaço entre cada modo de 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 alvos 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 Children
propriedade é a ContentProperty
da Layout<T>
classe e, portanto, não precisa ser definida explicitamente a partir de XAML.
Dica
Para obter o melhor desempenho de layout possível, siga as diretrizes em Otimizar desempenho de layout.
Orientação vertical
O XAML a seguir mostra como criar um orientado StackLayout
vertical 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 contendo Label
e BoxView
objetos verticaisStackLayout
. Por padrão, há seis unidades de espaço independentes de dispositivo entre os modos de exibição 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 uma orientação StackLayout
horizontal 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 um objeto horizontal StackLayout
que contém BoxView
, com seis unidades de espaço independentes de dispositivo entre os modos de exibição 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 modos de exibição filho
O espaçamento entre modos de exibição filho 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 um conteúdo Label
vertical StackLayout
e BoxView
objetos que não têm espaçamento entre eles:
Dica
A Spacing
propriedade pode ser definida como valores negativos para sobrepor modos de exibição filho.
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 dos modos de exibição filho
O tamanho e a posição dos modos de exibição filho dentro de um StackLayout
dependem dos valores dos modos de exibição filho HeightRequest
e WidthRequest
das propriedades, e dos valores de suas HorizontalOptions
e VerticalOptions
propriedades. Em uma vertical StackLayout
, os modos de exibição filho se expandem para preencher a largura disponível quando seu tamanho não está definido explicitamente. Da mesma forma, em um horizontal StackLayout
, os modos de exibição filho se expandem para preencher a altura disponível quando seu tamanho não é definido explicitamente.
As HorizontalOptions
propriedades e VerticalOptions
de um StackLayout
, e suas exibições filhas, podem ser definidas como campos da LayoutOptions
struct, que encapsula duas preferências de layout:
- O alinhamento determina a posição e o tamanho de um modo de exibição filho em seu layout pai.
- 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 um StackLayout
a menos que você precise. 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 aos valores padrão.
Alinhamento
O exemplo XAML a seguir define preferências de alinhamento em cada modo de 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 preferências de alinhamento são definidas nos Label
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 no 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 o Label
ocupará 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
, verifique se apenas um modo de exibição filho está definido 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
Um 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 profundo 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 }
}
}
},
// ...
}
};
}
}