Xamarin.Forms 中的布局选项

每个 Xamarin.Forms 视图都有 LayoutOptions 类型的 Horizo​​ntalOptions 和 VerticalOptions 属性。 本文解释了每个 LayoutOptions 值对视图的对齐方式和扩展的影响。

概述

LayoutOptions 结构封装两个布局首选项:

  • 对齐方式 - 视图的首选对齐方式,用于确定其父级布局中的位置和大小。
  • 扩展 - 仅由 StackLayout 使用,指示视图是否应使用可用的额外空间。

通过将 ViewHorizontalOptionsVerticalOptions 属性设置为 LayoutOptions 结构中的一个公共字段,可以将这些布局首选项应用于 View(相对于其父级而言)。 公共字段如下所示:

StartCenterEndFill 字段用于定义父布局中视图的对齐方式。

  • 对于水平对齐,StartView 放置在父布局的左侧,而对于垂直对齐,则将 View 放置在父布局的顶部。
  • 对于水平对齐和垂直对齐,CenterView 水平或垂直居中。
  • 对于水平对齐,EndView 放置在父布局的右侧,而对于垂直对齐,则将 View 放置在父布局的底部。
  • 对于水平对齐,Fill 可确保 View 填充父布局的宽度,而对于垂直对齐,则可确保 View 填充父布局的高度。

StartAndExpandCenterAndExpandEndAndExpandFillAndExpand 值用于定义对齐方式首选项,以及该视图在父级 StackLayout 内是否将占用更多可用空间。

注意

视图的 HorizontalOptionsVerticalOptions 属性的默认值为 LayoutOptions.Fill

对齐

当父布局包含未使用的空间(即父布局大于其所有子布局的总大小)时,对齐方式可控制视图在其父布局中的定位方式。

StackLayout 仅遵循与 StackLayout 方向相反的子视图上的 StartCenterEndFill LayoutOptions 字段。 因此,垂直方向的 StackLayout 中的子视图会将其 HorizontalOptions 属性设置为 StartCenterEndFill 字段之一: 同样,水平方向的 StackLayout 的子视图可以将其 VerticalOptions 属性设置为 StartCenterEndFill 字段之一。

StackLayout 不遵循与 StackLayout 方向相同的子视图上的 StartCenterEndFill LayoutOptions 字段。 因此,垂直方向的 StackLayout 会忽略在子视图的 VerticalOptions 属性上设置的 StartCenterEndFill 字段。 同样,水平方向的 StackLayout 会忽略在子视图的 HorizontalOptions 属性上设置的 StartCenterEndFill 字段。

注意

LayoutOptions.Fill 通常会重写使用 HeightRequestWidthRequest 属性指定的大小请求。

以下 XAML 代码示例演示了垂直方向的 StackLayout,其中每个子级 Label 都将其 HorizontalOptions 属性都设置为 LayoutOptions 结构中的四个对齐方式字段之一:

<StackLayout Margin="0,20,0,0">
  ...
  <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>

等效 C# 代码如下所示:

Content = new StackLayout
{
  Margin = new Thickness(0, 20, 0, 0),
  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 }
  }
};

此代码会生成如以下屏幕截图中所示的布局:

对齐布局选项

扩展

扩展控制视图是否会在 StackLayout 中占用更多可用空间。 如果 StackLayout 包含未使用的空间(即,StackLayout 大于其所有子视图的总大小),则请求扩展的所有子视图将均等地共享未使用的空间,方法是将所有子视图的 HorizontalOptionsVerticalOptions 属性设置为使用 AndExpand 后缀的 LayoutOptions 字段。 请注意,使用 StackLayout 中的所有空间时,“扩展”选项将不起作用。

StackLayout 只能按照其方向展开子视图。 因此,垂直方向的 StackLayout 可以扩展子视图,如果 StackLayout 包含未使用的空间,这些子视图会将其 VerticalOptions 属性设置为 StartAndExpandCenterAndExpandEndAndExpandFillAndExpand 字段中的其中一个字段。 同样,水平方向的 StackLayout 也可以扩展子视图,如果 StackLayout 包含未使用的空间,这些子视图会将其 HorizontalOptions 属性设置为 StartAndExpandCenterAndExpandEndAndExpandFillAndExpand 字段中的其中一个字段。

StackLayout 只能朝其自身的方向扩展子视图。 因此,在垂直方向的 StackLayout 上,将子视图上的 HorizontalOptions 属性设置为 StartAndExpand 的效果与将该属性设置为 Start 的效果相同。

注意

请注意,除非视图使用 LayoutOptions.FillAndExpand,否则启用扩展不会更改视图的大小。

以下 XAML 代码示例演示了垂直方向的 StackLayout,其中每个子级 Label 都将其 VerticalOptions 属性都设置为 LayoutOptions 结构中的四个扩展字段之一:

<StackLayout Margin="0,20,0,0">
  ...
  <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>

等效 C# 代码如下所示:

Content = new StackLayout
{
  Margin = new Thickness(0, 20, 0, 0),
  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 }
  }
};

此代码会生成如以下屏幕截图中所示的布局:

扩展布局选项

每个 LabelStackLayout 中都占据相同的空间量。 但是,只有最后一个 Label(可将 VerticalOptions 属性设置为 FillAndExpand)具有不同的大小。 另外,每个 Label 都用一个小红色 BoxView 隔开,这样可以很容易地看到 Label 所占据的空间。

总结

本文介绍了每个 LayoutOptions 结构值对视图的对齐方式和扩展的影响(相对其父视图而言)。 StartCenterEndFill 字段用于定义视图在父布局内​​的对齐方式,而 StartAndExpandCenterAndExpandEndAndExpandFillAndExpand 字段用于定义对齐方式首选项,并确定视图是否会在 StackLayout 内占用更多可用空间。