Share via


Xamarin.Forms StackLayout

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 tipo StackOrientation, representa a direção na qual as visões filho são posicionadas. O valor padrão dessa propriedade é Vertical.
  • Spacing, do tipo double, 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:

Captura de tela de um StackLayout orientado verticalmente

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:

Captura de tela de um StackLayout orientado horizontalmente

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:

Captura de tela de um StackLayout sem qualquer espaçamento

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 Startcampos , Center, Ende Fill são usados para definir o Label alinhamento dos objetos dentro do pai StackLayout:

Captura de tela de um StackLayout com opções de alinhamento definidas

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:

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 StartAndExpandcampos , CenterAndExpand, EndAndExpande 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:

Captura de tela de um StackLayout com opções de expansão definidas

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:

Captura de tela de objetos StackLayout aninhados

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 }
                        }
                    }
                },
                // ...
            }
        };
    }
}