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
?
Theory
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, it is 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?
-
Suffix
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.
-
No suffix: The children without the
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.
-
Example
To demonstrate the effect of different LayoutOptions
, we create a tiny example app. It consists of a gray StackLayout
with some padding and some spacing between its child elements.
static readonly StackLayout stackLayout = new StackLayout { BackgroundColor = Color.Gray, Padding = 2, Spacing = 2, };
The constructor of our App
adds eight child elements before assigning the StackLayout
to the MainPage
. Note that we use a device-dependent padding for the MainPage
to avoid elements being overlaid by the iOS status bar.
public App() { AddElement("Start", LayoutOptions.Start); AddElement("Center", LayoutOptions.Center); AddElement("End", LayoutOptions.End); AddElement("Fill", LayoutOptions.Fill); AddElement("StartAndExpand", LayoutOptions.StartAndExpand); AddElement("CenterAndExpand", LayoutOptions.CenterAndExpand); AddElement("EndAndExpand", LayoutOptions.EndAndExpand); AddElement("FillAndExpand", LayoutOptions.FillAndExpand); MainPage = new ContentPage { Padding = new Thickness(0, Device.OnPlatform(20, 0, 0), 0, 0), Content = stackLayout, }; }
The method AddElement
creates a new Label
with different text and corresponding layoutOption
. Its text is centered horizontally and vertically using the two properties HorizontalTextAlignment
and VerticalTextAlignment
.
Furthermore, it adds a flat yellow BoxView
. This will serve as a visual separator between the space occupied by the white labels.
static void AddElement(string text, LayoutOptions layoutOption) { stackLayout.Children.Add(new Label { Text = text, BackgroundColor = Color.White, HorizontalTextAlignment = TextAlignment.Center, VerticalTextAlignment = TextAlignment.Center, HorizontalOptions = layoutOption, VerticalOptions = layoutOption, WidthRequest = 160, HeightRequest = 25, }); stackLayout.Children.Add(new BoxView { HeightRequest = 1, Color = Color.Yellow, }); }
The screenshot shows the resulting layout. We make the following observations:
-
The different alignment is only visible if there is space available. If the
stackLayout
would not fill the page, we might not be able to see a difference between elements with optionsStart
orStartAndExpand
. -
Additional space is evenly proportioned amongst all labels with
Expand
suffix. To see this more clearly we added yellow horizontal lines – actually flatBoxView
s – between every two neighboring labels. Labels with more space than their requested height do not necessarily “fill” it. In this case the actual behavior is controlled by their alignment. E.g. they are either aligned on top, center or label of their space or fill it completely. -
If there is space available and no other expanding element – like in the horizontal direction – the alignment controls the element’s position even if it is not expanding, like the first four labels.