In Xamarin.Forms every View
has the two properties HorizontalOptions
and VerticalOptions
. Both are of type LayoutOptions
and can have one of the following values:
LayoutOptions.Start
LayoutOptions.Center
LayoutOptions.End
LayoutOptions.Fill
LayoutOptions.StartAndExpand
LayoutOptions.CenterAndExpand
LayoutOptions.EndAndExpand
LayoutOptions.FillAndExpand
Apparently it controls the view's alignment on the parent view. But how exactly is the behavior of each individual option? And what is the difference between Fill
and the suffix Expand
?
The StartAndExpand , CenterAndExpand , EndAndExpand , and FillAndExpand values are used to define the alignment preference, and whether the view will occupy more space if available within the parent StackLayout . The default value of a view's HorizontalOptions and VerticalOptions properties is LayoutOptions. Fill .
StackLayout organizes views in a one-dimensional line ("stack"), either horizontally or vertically. Views in a StackLayout can be sized based on the space in the layout, using layout options.
Start
, Center
, End
and Fill
define the view's alignment within its space.
Expand
defines whether it occupies more space if available.
The structure LayoutOptions
controls two distinct behaviors:
Alignment: How is the view aligned within the parent view?
Start
: For vertical alignment the view is moved to the top. For horizontal alignment this is usually the left-hand side. (But note, that on devices with right-to-left language setting this is the other way around, i.e. right aligned.)Center
: The view is centered.End
: Usually the view is bottom or right aligned. (On right-to-left languages, of course, left aligned.)Fill
: This alignment is slightly different. The view will stretch across the full size of the parent view.If the parent, however, is not larger then its children, you won't notice any difference between those alignments. Alignment only matters for parent views with additional space available.
Expansion: Will the element occupy more space if available?
Expand
: If the parent view is larger than the combined size of all its children, i.e. additional space is available, then the space is proportioned amongst child views with that suffix. Those children will "occupy" their space, but do not necessarily "fill" it. We'll have a look on this behavior in the example below.Expand
suffix won't get additional space, even if more space is available.Again, if the parent view is not larger than its children, the expansion suffix does not make any difference as well.
Let's have a look on the following example to see the difference between all eight layout options.
The app contains a dark gray StackLayout
with eight nested white buttons, each of which is labeled with its vertical layout option. When clicking on one of the buttons, it assignes its vertical layout option to the stack layout. This way we can easily test the interaction of views with parents, both with different layout option.
(The last few lines of code add additional yellow boxes. We'll come back to this in a moment.)
public static class App
{
static readonly StackLayout stackLayout = new StackLayout {
BackgroundColor = Color.Gray,
VerticalOptions = LayoutOptions.Start,
Spacing = 2,
Padding = 2,
};
public static Page GetMainPage()
{
AddButton("Start", LayoutOptions.Start);
AddButton("Center", LayoutOptions.Center);
AddButton("End", LayoutOptions.End);
AddButton("Fill", LayoutOptions.Fill);
AddButton("StartAndExpand", LayoutOptions.StartAndExpand);
AddButton("CenterAndExpand", LayoutOptions.CenterAndExpand);
AddButton("EndAndExpand", LayoutOptions.EndAndExpand);
AddButton("FillAndExpand", LayoutOptions.FillAndExpand);
return new NavigationPage(new ContentPage {
Content = stackLayout,
});
}
static void AddButton(string text, LayoutOptions verticalOptions)
{
stackLayout.Children.Add(new Button {
Text = text,
BackgroundColor = Color.White,
VerticalOptions = verticalOptions,
HeightRequest = 20,
Command = new Command(() => {
stackLayout.VerticalOptions = verticalOptions;
(stackLayout.ParentView as Page).Title = "StackLayout: " + text;
}),
});
stackLayout.Children.Add(new BoxView {
HeightRequest = 1,
Color = Color.Yellow,
});
}
}
The following screenshots show the result when clicking on each of the eight buttons. We make the following observations:
stackLayout
is tight (does not Fill
the page), the vertical layout option of each Button
is negligible.stackLayout
is larger (e.g. via Fill
alignment) and the individual buttons have the Expand
suffix.Expand
suffix. To see this more clearly we added yellow horizontal lines between every two neighboring buttons.VerticalOptions
.Here you find the corresponding high-resolution screenshots.
There is a bit of a bug in the current version of Xamarin.Forms; maybe it has been there a while.
CenterAndExpand
generally doesn't expand, and working around it can be confusing.
For example if you have a StackLayout
set to CenterAndExpand
, then you put a label inside that also set to CenterAndExpand
you would expect a label that is full width of the StackLayout
. Nope. It won't expand. You have to set the StackLayout
to "FillAndExpand
" to get the nested Label object to expand to the full width of the StackLayout
, then tell the Label to center the text, not itself as an object, with HorizontalTextAlignment="Center"
. In my experience you need both the parent and nested child to be set to FillAndExpand
if you really want to make sure it expands to fit.
<StackLayout HorizontalOptions="FillAndExpand"
Orientation="Vertical"
WidthRequest="300">
<Label BackgroundColor="{StaticResource TileAlerts}"
HorizontalOptions="FillAndExpand"
Style="{StaticResource LabelStyleReversedLrg}"
HorizontalTextAlignment="Center"
Text="Alerts" />
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With