10

How do I evenly distribute 4 controls within a Xamarin Forms horizontal StackLayout. I have it looking decent on an iPhone 4S but lousy on an iPhone 6 or iPad. The horizontal stack layout is the list item in a ListView. I've tried a relative layout and a 1 row grid. But what I have looks best (on the the 4S). Thanks.

I have a button, label, label, and a button, in that order.

        stackLayout = new StackLayout {
            Orientation = StackOrientation.Horizontal,
            HorizontalOptions = LayoutOptions.Center
        };
        deleteButton.Image = "minus.png";
        deleteButton.HorizontalOptions = LayoutOptions.Start;

        //label text width may vary from 4 to 16 characters
        displayLabel.SetBinding(Label.TextProperty, "Text");
        displayLabel.HorizontalOptions = LayoutOptions.Center;
        displayLabel.WidthRequest = 125;

        //label text is always 8 characters
        displayLabel2.SetBinding(Label.TextProperty, "Text2");
        displayLabel2.HorizontalOptions = LayoutOptions.Center;

        button2.Image = "plus.png";
        button2.HorizontalOptions = LayoutOptions.EndAndExpand;

        stackLayout.Children.Add(deleteButton);
        stackLayout.Children.Add(displayLabel);
        stackLayout.Children.Add(displayLabel2);
        stackLayout.Children.Add(button2);
Phil O
  • 1,588
  • 4
  • 28
  • 52
  • Just a question: does this absolutely need to be a StackLayout? If not, then you could consider a Grid which can handle this quite easily for you. – Demitrian Aug 25 '15 at 14:30
  • I tried a grid of 1 row with 4 columns but for some reason, the 4 items did not align properly. – Phil O Aug 25 '15 at 18:26

1 Answers1

23

Using StackLayout:

using Xamarin.Forms;

var label1 = new Label() {
    Text = "label1",
    HorizontalOptions = LayoutOptions.FillAndExpand, //OR CenterAndExpand
};

var label2 = new Label() {
    Text = "label2",
    HorizontalOptions = LayoutOptions.FillAndExpand, //OR CenterAndExpand
};

var label3 = new Label() {
    Text = "label3",
    HorizontalOptions = LayoutOptions.FillAndExpand, //OR CenterAndExpand
};

var label4 = new Label() {
    Text = "label4",
    HorizontalOptions = LayoutOptions.FillAndExpand, //OR CenterAndExpand
};

var stackLayout = new StackLayout 
{
    Orientation = StackOrientation.Horizontal,
    HorizontalOptions = LayoutOptions.FillAndExpand,
    Children = {
        label1,
        label2,
        label3,
        label4,
    }
};

RootPage.Children.Add(new ContentPage {
    Padding = 10,
    Content = stackLayout
});

Using Grid:

using Xamarin.Forms;

    var label1 = new Label() {
    Text = "label1",
};

var label2 = new Label() {
    Text = "label2",
};

var label3 = new Label() {
    Text = "label3",
};

var label4 = new Label() {
    Text = "label4",
};

var gridLayout = new Grid 
{
    HorizontalOptions = LayoutOptions.FillAndExpand,
    ColumnDefinitions = new ColumnDefinitionCollection() {
        new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) },
        new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) },
        new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) },
        new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) },
    },
    RowDefinitions = new RowDefinitionCollection() {
        new RowDefinition() { Height = GridLength.Auto }
    }
};

gridLayout.Children.Add(label1, 0, 0);
gridLayout.Children.Add(label2, 1, 0);
gridLayout.Children.Add(label3, 2, 0);
gridLayout.Children.Add(label4, 3, 0);

RootPage.Children.Add(new ContentPage {
    Padding = 10,
    Content = gridLayout
});
Daniel Luberda
  • 7,374
  • 1
  • 32
  • 40
  • Thank you Daniel. FillAndExpand was the key to using a stack layout. I did have to give my second item a width request (since it's width varies) to keep all four columns aligned from row to row. I'll try your CenterAndExpand version and grid implementations shortly. – Phil O Aug 26 '15 at 12:59
  • No problem. You can read more about LayoutOptions here: http://stackoverflow.com/questions/25338533/what-is-the-difference-between-xamarin-forms-layoutoptions-especially-fill-and – Daniel Luberda Aug 26 '15 at 13:02
  • Quick follow up question. The first item is dynamic, in that it only displays sometimes, when it doesn't display the effective first item (label2) appears to be pinned to the left most end of the row, how do I add some padding or space to the left of label2? – Phil O Aug 26 '15 at 13:05
  • I don't know if I understand correctly, but if you want to leave even space when `Label` is not visible, you could replace `Label` with `ContentView` with `Content` set to your `Label`. Then just set the `Visibility` of `Label` to `true` or `false`. With this the even spacing won't be affected when you label is not visible. – Daniel Luberda Aug 26 '15 at 13:27
  • Thanks, I'll try that. – Phil O Aug 26 '15 at 18:21