Xamarin.Form的LayoutOptions有什么区别,特别是Fill和Expand?

在Xamarin.Forms中,每个View都有两个属性HorizontalOptionsVerticalOptions 。 两者都是LayoutOptionstypes,可以具有以下值之一:

  • LayoutOptions.Start
  • LayoutOptions.Center
  • LayoutOptions.End
  • LayoutOptions.Fill
  • LayoutOptions.StartAndExpand
  • LayoutOptions.CenterAndExpand
  • LayoutOptions.EndAndExpand
  • LayoutOptions.FillAndExpand

显然,它控制父视图上的视图alignment。 但是,每个选项的行为究竟如何呢? Fill和后缀Expand什么区别?

简短的回答

StartCenterEndFill 在其空间内定义视图的alignment

Expand定义是否占用更多空间(如果可用)。

理论

结构LayoutOptions控制两个不同的行为:

  1. alignment: 如何在父视图内alignment视图?

    • Start :对于垂直alignment,视图移动到顶部。 对于水平alignment,这通常是左侧。 (但请注意,在设置从右到左语言设置这是另一种方式,即右alignment。)
    • Center :视图居中。
    • End :通常视图是alignment的。 (在从右到左的语言当然左alignment。)
    • Fill :这种alignment略有不同。 该视图将横跨父视图的整个大小。

    但是,如果父母不小于孩子,则不会注意到这些alignment之间的区别。 alignment仅对父视图有重要的意义,并有更多的可用空间。

  2. 扩展: 如果可用,元素会占用更多的空间吗?

    • 后缀Expand :如果父级视图大于其所有子级的组合大小,即额外的空间可用,则该空间在具有该后缀的子级视图之间成比例。 这些孩子会“占据”他们的空间,但不一定“填补”它。 我们将在下面的例子中看看这个行为。
    • 没有后缀:即使有更多空间可用,无Expand后缀的子项也不会获得额外的空间。

    同样,如果父视图不大于子视图,则扩展后缀也不会有任何区别。

让我们看看下面的例子,看看所有八个布局选项之间的区别。

该应用程序包含一个深灰色StackLayout与八个嵌套的白色button,其中每个标有垂直布局选项。 点击其中一个button时,会将其垂直布局选项分配给堆栈布局。 这样我们可以很容易地testing视图与父母的交互,两者都有不同的布局选项。

(最后几行代码添加了额外的黄色框,我们稍后再回来。)

 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, }); } } 

以下屏幕截图显示了单击八个button中的每一个时的结果。 我们提出以下意见:

  • 只要父stackLayout紧密(不Fill页面),每个Button的垂直布局选项可以忽略不计。
  • 垂直布局选项只在stackLayout较大(例如通过Fillalignment方式)并且各个button具有Expand后缀时才重要。
  • 额外的空间在Expand后缀的所有button之间成比例。 为了更清楚地看到,我们在每两个相邻的button之间添加了黄色的水平线。
  • 比他们要求的高度更多空间的button不一定“填充”它。 在这种情况下,实际行为是通过alignment来控制的。 例如,他们要么alignment在他们的空间的顶部,中心或button,要么完全填充。
  • 所有button跨越布局的整个宽度,因为我们只修改VerticalOptions

截图

在这里您可以find相应的高分辨率屏幕截图。

在当前版本的Xamarin.Forms中存在一些缺陷, 也许它已经有一段时间了。

CenterAndExpand一般不会扩展,解决它可能会造成混淆。

例如,如果将一个StackLayout设置为StackLayout ,那么您将一个标签放在StackLayout ,您将会看到一个标签是StackLayout整个宽度。 不。 它不会扩大。 您必须将StackLayout设置为“ FillAndExpand ”以使嵌套的Label对象扩展到StackLayout的整个宽度,然后告诉Label将文本(不是对象本身)居中StackLayoutHorizontalTextAlignment="Center" 。 根据我的经验,如果你真的想确保扩展到合适的话,你需要将父级和嵌套子级设置为FillAndExpand

  <StackLayout HorizontalOptions="FillAndExpand" Orientation="Vertical" WidthRequest="300"> <Label BackgroundColor="{StaticResource TileAlerts}" HorizontalOptions="FillAndExpand" Style="{StaticResource LabelStyleReversedLrg}" HorizontalTextAlignment="Center" Text="Alerts" />