182

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?

Falko
  • 17,076
  • 13
  • 60
  • 105

3 Answers3

355

Short answer

Start, Center, End and Fill define the view's alignment within its space.

Expand defines whether it occupies more space if available.

Theory

The structure LayoutOptions controls two distinct behaviors:

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

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

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:

  • As long as the parent stackLayout is tight (does not Fill the page), the vertical layout option of each Button is negligible.
  • The vertical layout option only matters if the stackLayout is larger (e.g. via Fill alignment) and the individual buttons have the Expand suffix.
  • Additional space is evently proportioned amongst all buttons with Expand suffix. To see this more clearly we added yellow horizontal lines between every two neighboring buttons.
  • Buttons 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 button of their space or fill it completely.
  • All buttons span across the whole width of the layout, since we only modify the VerticalOptions.

Screenshots

Here you find the corresponding high-resolution screenshots.

Falko
  • 17,076
  • 13
  • 60
  • 105
  • 6
    image looks like [[midfing]] , lol. just kidding it was really helpful – Joy Rex Feb 12 '15 at 12:14
  • 1
    @JoyRex: Well, maybe [this version](http://xforms-kickstarter.com/#layout-options) is a bit less confusing. ;) – Falko Feb 12 '15 at 12:49
  • And let say everything is wrapped into an AbsoluteLayout? Will it look like [[midfing]] ? – Léon Pelletier May 18 '15 at 22:26
  • 4
    I have confused with above output. start & startAndExpand both are same output.. What is difference between these? can you give explanation if possible.. – Ranjithkumar Aug 29 '16 at 05:02
  • 1
    `FillAndExpand` is what you want, 99% fo the time – Stephane Delcroix Dec 07 '16 at 07:37
  • 2
    @RanjithKumar They are the same. It StackLayout was nested in another parent then its FillAndExpand could make a difference - it would expand within *its* parent. – Miha Markic Aug 31 '17 at 09:00
  • Expand doesn't seem to do anything. Both rows of images are the same. – Ian Warburton Apr 17 '19 at 18:23
  • 1
    @IanWarburton: For the StackLayout, yes. In this case it get's all the vertical space anyway, because it's the only element on the page. But the buttons behave differently with the `Expand` option, since only expanding elements can share remaining space. – Falko Apr 17 '19 at 19:38
18

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" />
Clint StLaurent
  • 1,238
  • 12
  • 11
  • 3
    "...you would expect a label that is full width of the StackLayout." This assumption is incorrect. `Expand` is only used for children of StackLayout. So, if your StackLayout is the root, or not in another StackLayout, `Expand` has no affect. Instead, any option other than Fill would act as a "wrap content" for sizing, which is what you see. – therealjohn Dec 06 '16 at 20:43
  • In addition, expansion only works for LayoutOptions that are of the same orientation of the StackLayout. In this case, the layout is "Vertical", but the options in question are Horizontal (opposites). – therealjohn Dec 06 '16 at 21:06
  • 1
    The term "AndExpand" is ambiguous. It could be interpreted as "expand as much as possible" or "expand only as much as needed". I think Microsoft should change the terms to something less confusing, like "CenterAndExpandToParent" or "CenterAndExpandAsNeeded" – SendETHToThisAddress Jun 22 '20 at 22:50
2

Falko gave a good explanation but I wanted to add onto that with another visual and how these tags work in xaml, which is what I prefer to use most of the time. I made a simple project for testing out display results. Here is the Xaml for the Main Page:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Alignments.MainPage"
             BackgroundColor="White">


    <StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" BackgroundColor="LightGray" Padding="1" Margin="30">
        <Label Text="Vert: EndAndExpand, Horz: EndAndExpand" VerticalOptions="EndAndExpand" HorizontalOptions="EndAndExpand" BackgroundColor="White"/>
    </StackLayout>


</ContentPage>

As you can see it's a very simple StackLayout with a Label inside. For each image below I kept the StackLayout the same, I just changed the horizontal and vertical options for the Entry and changed the text to show the selected options, so you can see how the Entry moves and resizes.

Start vs StartAndExpand Here is the code used for Start:

<Label Text="Vert: Start, Horz: Start" VerticalOptions="Start" HorizontalOptions="Start" BackgroundColor="White"/>

And the code used for StartAndExpand:

<Label Text="Vert: StartAndExpand, Horz: StartAndExpand" VerticalOptions="StartAndExpand" HorizontalOptions="StartAndExpand" BackgroundColor="White"/>

As you can see there is no difference visually other than there is more text used in the StartAndExpand option. This was tested on my Samsung A30 physical device. These may display differently on different devices, but I think all of the images here collectively show that there are some bugs in Xamarin. For the rest I will just show the screenshots, I think they are self-explanitory.

End vs EndAndExpand

Center vs CenterAndExpand

Fill vs FillAndExpand

I also recommend taking a look at the Microsoft documentation for some additional details. Notable is that "Expansion is used only by a StackLayout".

SendETHToThisAddress
  • 2,756
  • 7
  • 29
  • 54
  • 1
    Nice visualization. But I don't see why this should show bugs in Xamarin. What might be confusing is that the labels can occupy more space than their white background (the gray regions in my example). So a "Vert Center" label is centered within the space it occupies - not within the whole page. Apparently, after almost six years this topic is still as confusing as it was back than. – Falko Jun 23 '20 at 05:00