Xamarin.Form的LayoutOptions有什么区别,特别是Fill和Expand?
在Xamarin.Forms中,每个View
都有两个属性HorizontalOptions
和VerticalOptions
。 两者都是LayoutOptions
types,可以具有以下值之一:
-
LayoutOptions.Start
-
LayoutOptions.Center
-
LayoutOptions.End
-
LayoutOptions.Fill
-
LayoutOptions.StartAndExpand
-
LayoutOptions.CenterAndExpand
-
LayoutOptions.EndAndExpand
-
LayoutOptions.FillAndExpand
显然,它控制父视图上的视图alignment。 但是,每个选项的行为究竟如何呢? Fill
和后缀Expand
什么区别?
简短的回答
Start
, Center
, End
和Fill
在其空间内定义视图的alignment 。
Expand
定义是否占用更多空间(如果可用)。
理论
结构LayoutOptions
控制两个不同的行为:
-
alignment: 如何在父视图内alignment视图?
-
Start
:对于垂直alignment,视图移动到顶部。 对于水平alignment,这通常是左侧。 (但请注意,在设置从右到左语言设置这是另一种方式,即右alignment。) -
Center
:视图居中。 -
End
:通常视图是alignment的。 (在从右到左的语言当然左alignment。) -
Fill
:这种alignment略有不同。 该视图将横跨父视图的整个大小。
但是,如果父母不小于孩子,则不会注意到这些alignment之间的区别。 alignment仅对父视图有重要的意义,并有更多的可用空间。
-
-
扩展: 如果可用,元素会占用更多的空间吗?
- 后缀
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
较大(例如通过Fill
alignment方式)并且各个button具有Expand
后缀时才重要。 - 额外的空间在
Expand
后缀的所有button之间成比例。 为了更清楚地看到,我们在每两个相邻的button之间添加了黄色的水平线。 - 比他们要求的高度更多空间的button不一定“填充”它。 在这种情况下,实际行为是通过alignment来控制的。 例如,他们要么alignment在他们的空间的顶部,中心或button,要么完全填充。
- 所有button跨越布局的整个宽度,因为我们只修改
VerticalOptions
。
在这里您可以find相应的高分辨率屏幕截图。
在当前版本的Xamarin.Forms中存在一些缺陷, 也许它已经有一段时间了。
CenterAndExpand
一般不会扩展,解决它可能会造成混淆。
例如,如果将一个StackLayout
设置为StackLayout
,那么您将一个标签放在StackLayout
,您将会看到一个标签是StackLayout
整个宽度。 不。 它不会扩大。 您必须将StackLayout
设置为“ FillAndExpand
”以使嵌套的Label对象扩展到StackLayout
的整个宽度,然后告诉Label将文本(不是对象本身)居中StackLayout
在HorizontalTextAlignment="Center"
。 根据我的经验,如果你真的想确保扩展到合适的话,你需要将父级和嵌套子级设置为FillAndExpand
。
<StackLayout HorizontalOptions="FillAndExpand" Orientation="Vertical" WidthRequest="300"> <Label BackgroundColor="{StaticResource TileAlerts}" HorizontalOptions="FillAndExpand" Style="{StaticResource LabelStyleReversedLrg}" HorizontalTextAlignment="Center" Text="Alerts" />