Xamarin.Forms StackLayout
StackLayout
は、子ビューを水平方向または垂直方向の 1 次元のスタックに編成します。 既定では、StackLayout
は垂直方向に配置されます。 さらに StackLayout
は、他の子レイアウトを含む親レイアウトとして使用できます。
StackLayout
クラスには、次のプロパティが定義されています。
Orientation
(StackOrientation
型): 子ビューが配置される方向を表します。 このプロパティの既定値はVertical
です。double
型 のSpacing
は、各子ビュー間のスペースの量を示します。 このプロパティの既定値は、デバイスに依存しない 6 単位です。
これらのプロパティは、BindableProperty
オブジェクトがサポートしています。つまり、プロパティをデータ バインディングの対象にして、スタイル設定することができます。
StackLayout
クラスは、IList<T>
型の Children
プロパティを定義する Layout<T>
クラスから派生します。 Children
プロパティは Layout<T>
クラスの ContentProperty
であるため、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>
この例では、Label
オブジェクトと BoxView
オブジェクトを含んだ垂直方向の StackLayout
を作成します。 既定では、子ビュー間には、デバイスに依存しない 6 単位のスペースがあります。
同等の 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 }
}
};
}
}
Note
Margin
プロパティの値は、要素とその隣接する要素の間の距離を表します。 詳細については「Margin and Padding」 (余白とスペース) を参照してください。
水平方向
次の 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>
この例では、子ビュー間にデバイスに依存しない 6 単位のスペースを持つ、BoxView
オブジェクトを含む水平方向の 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 }
}
};
}
子ビュー間のスペース
Spacing
プロパティを double
値に設定すると、StackLayout
内の子ビュー間の間隔を変更できます。
<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>
この例では、間にスペースのない Label
オブジェクトと BoxView
オブジェクトを含む垂直方向の StackLayout
を作成します。
ヒント
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
内の子ビューのサイズと位置は、子ビューの HeightRequest
プロパティと WidthRequest
プロパティの値、および HorizontalOptions
プロパティと VerticalOptions
プロパティの値によって異なります。 垂直方向の StackLayout
では、サイズが明示的に設定されていない場合、子ビューは使用可能な幅に合わせて広がります。 同様に、水平方向の StackLayout
では、サイズが明示的に設定されていない場合、子ビューは使用可能な高さに合わせて広がります。
StackLayout
の HorizontalOptions
プロパティと VerticalOptions
プロパティ、その子ビューは、2 つのレイアウト設定をカプセル化する LayoutOptions
構造体のフィールドに設定できます。
- "配置" は、親レイアウト内の子ビューの位置とサイズを設定します。
- "展開" は、子ビューが、追加のスペースを使用できる場合に、使う必要があるかどうかを示します。
ヒント
必要な場合を除き、StackLayout
の HorizontalOptions
と VerticalOptions
のプロパティを設定しないでください。 既定値の LayoutOptions.Fill
と LayoutOptions.FillAndExpand
で、レイアウトの最適化が最大になります。 これらのプロパティの変更にはコストがかかり、既定値に戻すように設定する場合でも、メモリを消費します。
Alignment
次の 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
内の位置を制御します。 Start
、Center
、End
、Fill
の各フィールドは、親 StackLayout
内の Label
オブジェクトの配置を定義するために使用されます。
StackLayout
は、StackLayout
の方向とは反対方向にある子ビューの配置設定のみに従います。 したがって、垂直方向の StackLayout
内の Label
子ビューは、それらの HorizontalOptions
プロパティを次の配置フィールドの 1 つに設定します。
Start
:Label
をStackLayout
の左側に配置します。Center
:Label
をStackLayout
の中央に配置します。End
:Label
をStackLayout
の右側に配置します。Fill
:Label
でStackLayout
の幅が埋まるようにします。
同等の 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 例では、StackLayout
内の各 Label
に展開設定を設定します。
<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>
この例では、StackLayout
内でのサイズを制御するために、Label
オブジェクトに拡張設定が設定されています。 StartAndExpand
、CenterAndExpand
、EndAndExpand
、FillAndExpand
フィールドは、配置設定と、親 StackLayout
内で使用できる場合に Label
がより多くのスペースを占有するかどうかを定義するために使われます。
StackLayout
は子ビューをその方向にのみ展開できます。 したがって、垂直方向の StackLayout
は、VerticalOptions
プロパティをいずれかの展開フィールドに設定する Label
子ビューを展開できます。 つまり、垂直方向の配置では、各 Label
が StackLayout
内で同じ量のスペースを占有します。 ただし、VerticalOptions
プロパティを FillAndExpand
に設定する最後の Label
のみ、サイズが異なります。
ヒント
StackLayout
を使う場合は、1 つの子ビューのみが 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
オブジェクトは水平方向に配置されます。
重要
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 }
}
}
},
// ...
}
};
}
}