每个 Xamarin.Forms 视图都有 LayoutOptions 类型的 HorizontalOptions 和 VerticalOptions 属性。 本文解释了每个 LayoutOptions 值对视图的对齐方式和扩展的影响。
概述
LayoutOptions 结构封装两个布局首选项:
- 对齐方式 - 视图的首选对齐方式,用于确定其父级布局中的位置和大小。
- 扩展 - 仅由 StackLayout使用,指示视图是否应使用可用的额外空间。
通过将 View 的 HorizontalOptions 或 VerticalOptions 属性设置为 LayoutOptions 结构中的一个公共字段,可以将这些布局首选项应用于 View(相对于其父级而言)。 公共字段如下所示:
Start、Center、End 和Fill 字段用于定义父布局中视图的对齐方式。
- 对于水平对齐,Start将View放置在父布局的左侧,而对于垂直对齐,则将View放置在父布局的顶部。
- 对于水平对齐和垂直对齐,Center将View水平或垂直居中。
- 对于水平对齐,End将View放置在父布局的右侧,而对于垂直对齐,则将View放置在父布局的底部。
- 对于水平对齐,Fill可确保View填充父布局的宽度,而对于垂直对齐,则可确保View填充父布局的高度。
StartAndExpand、CenterAndExpand、EndAndExpand 和 FillAndExpand 值用于定义对齐方式首选项,以及该视图在父级 StackLayout 内是否将占用更多可用空间。
注意
视图的 HorizontalOptions 和 VerticalOptions 属性的默认值为 LayoutOptions.Fill。
对齐
当父布局包含未使用的空间(即父布局大于其所有子布局的总大小)时,对齐方式可控制视图在其父布局中的定位方式。
StackLayout 仅遵循与 StackLayout 方向相反的子视图上的 Start、Center、End 和 Fill LayoutOptions 字段。 因此,垂直方向的 StackLayout 中的子视图会将其 HorizontalOptions 属性设置为 Start、Center、End 或 Fill 字段之一: 同样,水平方向的 StackLayout 的子视图可以将其 VerticalOptions 属性设置为 Start、Center、End 或 Fill 字段之一。
StackLayout 不遵循与 StackLayout 方向相同的子视图上的 Start、Center、End 和 Fill LayoutOptions 字段。 因此,垂直方向的 StackLayout 会忽略在子视图的 VerticalOptions 属性上设置的 Start、Center、End 和 Fill 字段。 同样,水平方向的 StackLayout 会忽略在子视图的 HorizontalOptions 属性上设置的 Start、Center、End 或 Fill 字段。
注意
LayoutOptions.Fill 通常会重写使用 HeightRequest 和 WidthRequest 属性指定的大小请求。
以下 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 大于其所有子视图的总大小),则请求扩展的所有子视图将均等地共享未使用的空间,方法是将所有子视图的 HorizontalOptions 或 VerticalOptions 属性设置为使用 AndExpand 后缀的 LayoutOptions 字段。 请注意,使用 StackLayout 中的所有空间时,“扩展”选项将不起作用。
StackLayout 只能按照其方向展开子视图。 因此,垂直方向的 StackLayout 可以扩展子视图,如果 StackLayout 包含未使用的空间,这些子视图会将其 VerticalOptions 属性设置为 StartAndExpand、CenterAndExpand、EndAndExpand 或 FillAndExpand 字段中的其中一个字段。 同样,水平方向的 StackLayout 也可以扩展子视图,如果 StackLayout 包含未使用的空间,这些子视图会将其 HorizontalOptions 属性设置为 StartAndExpand、CenterAndExpand、EndAndExpand 或 FillAndExpand 字段中的其中一个字段。
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 }
  }
};
此代码会生成如以下屏幕截图中所示的布局:
每个 Label 在 StackLayout 中都占据相同的空间量。 但是,只有最后一个 Label(可将 VerticalOptions 属性设置为 FillAndExpand)具有不同的大小。 另外,每个 Label 都用一个小红色 BoxView 隔开,这样可以很容易地看到 Label 所占据的空间。
总结
本文介绍了每个 LayoutOptions 结构值对视图的对齐方式和扩展的影响(相对其父视图而言)。 Start、Center、End 和 Fill 字段用于定义视图在父布局内的对齐方式,而 StartAndExpand、CenterAndExpand、EndAndExpand 和 FillAndExpand 字段用于定义对齐方式首选项,并确定视图是否会在 StackLayout 内占用更多可用空间。

