Xamarin.Forms StackLayout

Download Sample 下載範例

Xamarin.Forms StackLayout

StackLayout 以水準或垂直方式組織一維堆疊中的子檢視。 根據預設,StackLayout 是垂直方向。 此外, StackLayout 也可以做為包含其他子版面配置的父版面配置。

類別 StackLayout 會定義下列屬性:

  • Orientation類型 StackOrientation 為 的 ,代表子檢視的位置方向。 此屬性的預設值為 Vertical
  • Spacing類型 double 為 的 ,表示每個子檢視之間的空間量。 此屬性的預設值是六個與裝置無關的單位。

這些屬性是由 物件所 BindableProperty 支援,這表示屬性可以是資料系結和樣式的目標。

類別 StackLayout 衍生自 Layout<T> 類別,這個類別會 Children 定義 類型的 IList<T> 屬性。 屬性 ChildrenContentProperty 類別的 Layout<T> ,因此不需要從 XAML 明確設定。

提示

若要取得最佳的版面配置效能,請遵循 優化版面配置效能的指導方針。

垂直方向

下列 XAML 示範如何建立包含不同子檢視的垂直導向 StackLayout

<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>

這個範例會建立包含 LabelBoxView 物件的垂直 StackLayout 。 根據預設,子檢視之間有六個與裝置無關的空間單位:

Screenshot of a vertically oriented StackLayout

對等的 C# 程式碼為:

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 }
            }
        };
    }
}

注意

屬性的值 Margin 代表專案與其相鄰元素之間的距離。 如需詳細資訊,請參閱邊界和邊框距離

水準方向

下列 XAML 示範如何藉由將其 Orientation 屬性設定為 Horizontal ,以水準方向 StackLayout 建立 :

<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>

本範例會建立包含 物件的水準 StackLayoutBoxView ,子檢視之間有六個與裝置無關的空間單位:

Screenshot of a horizontally oriented StackLayout

對等的 C# 程式碼為:

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 }
        }
    };
}

子檢視之間的空間

中的子檢視 StackLayout 之間的間距可以藉由將 屬性設定 Spacingdouble 值來變更:

<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>

此範例會 StackLayout 建立垂直包含 LabelBoxView 物件,這些物件之間沒有間距:

Screenshot of a StackLayout without any spacing

提示

屬性 Spacing 可以設定為負值,讓子檢視重迭。

對等的 C# 程式碼為:

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 }
            }
        };
    }
}

子檢視的位置和大小

StackLayout 子檢視的大小和位置取決於子檢視和 HeightRequestWidthRequest 屬性的值,以及其 HorizontalOptionsVerticalOptions 屬性的值。 在垂直 StackLayout 中,子檢視會在未明確設定其大小時展開以填滿可用的寬度。 同樣地,在水準 StackLayout 中,子檢視會展開,以在未明確設定其大小時填滿可用的高度。

HorizontalOptionsVerticalOptions 屬性 StackLayout 及其子檢視可以設定為結構中的 LayoutOptions 欄位,其封裝兩個版面配置喜好設定:

  • 對齊 會決定子檢視在其父版面配置中的位置和大小。
  • 展開 表示子檢視是否應該使用額外的空間,如果有的話。

提示

除非您需要 ,否則請勿設定 HorizontalOptionsStackLayoutVerticalOptions 屬性。 LayoutOptions.FillLayoutOptions.FillAndExpand 的預設值可提供最優異的版面配置最佳化。 變更這些屬性的成本並耗用記憶體,即使將它們設定回預設值也一定。

對齊

下列 XAML 範例會在 中的每個 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>

在此範例中 Label ,會在 物件上設定對齊喜好設定,以控制其在 內 StackLayout 的位置。 、、 和 欄位是用來定義父 StackLayout 系內物件的對齊方式 LabelFillEndCenterStart

Screenshot of a StackLayout with alignment options set

StackLayout 只會遵循子檢視上的對齊喜好設定,而這與 StackLayout 方向相反。 因此,垂直方向 StackLayout 中的 Label 子檢視會將其 HorizontalOptions 屬性設定為其中一個對齊欄位:

對等的 C# 程式碼為:

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 }
            }
        };
    }
}

擴充

下列 XAML 範例會在 中的每個 StackLayoutLabel 設定擴充喜好設定:

<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>

在此範例中,擴充喜好設定是在 物件上設定, Label 以控制其大小 StackLayoutStartAndExpandCenterAndExpandEndAndExpandFillAndExpand 欄位是用來定義對齊喜好設定,以及 Label 如果父系 StackLayout 內可用,是否佔用更多空間:

Screenshot of a StackLayout with expansion options set

StackLayout 只會讓子檢視往其方向延展。 因此,垂直方向的 StackLayout 若要延展 Label 子檢視,其 VerticalOptions 屬性須設定為其中一個延展欄位。 這表示,在垂直對齊的情況下,每個 Label 會佔用 StackLayout 內相同數量的空間。 不過,最後的 Label 會將其 VerticalOptions 屬性設為 FillAndExpand,因此只有其大小不同。

提示

使用 StackLayout 時,請確定只有一個子檢視設定為 LayoutOptions.Expands 。 此屬性可確保指定的子系會佔用 StackLayout 所能提供的最大空間,重複執行這些計算將會浪費資源。

對等的 C# 程式碼為:

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 }
        }
    };
}

重要

如果 StackLayout 中的所有空間都已使用,則延展喜好設定不會有作用。

如需對齊和展開的詳細資訊,請參閱中的版 Xamarin.Forms 面配置選項

巢狀 StackLayout 物件

StackLayout可用來做為包含巢狀子 StackLayout 物件的父版面配置,或其他子版面配置。

下列 XAML 顯示巢狀 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>

在此範例中,父系 StackLayout 會在 物件內 Frame 包含巢狀 StackLayout 物件。 父系 StackLayout 垂直方向,而子 StackLayout 物件水準方向:

Screenshot of nested StackLayout objects

重要

巢狀 StackLayout 物件和其他版面配置越深,巢狀配置就越會影響效能。 如需詳細資訊,請參閱 選擇正確的版面配置

對等的 C# 程式碼為:

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