Xamarin.Forms FlexLayout
使用 FlexLayout 堆叠或包装子视图集合。
Xamarin.FormsFlexLayout
是 Xamarin.Forms 版本 3.0 中的新增功能。 它基于 CSS 灵活框布局模块,通常称为弹性布局或弹性框,之所以这样命名,是因为它包含了许多灵活的选项来安排布局中的子元素。
FlexLayout
类似于 Xamarin.FormsStackLayout
,因为它可以在堆栈中水平和垂直排列其子级。 但是,如果单个行或列中容纳太多子级,则 FlexLayout
也能够包装其子级,并且还具有许多用于方向、对齐和适应不同屏幕大小的选项。
FlexLayout
派生自 Layout<View>
,并继承类型 IList<View>
的 Children
属性。
FlexLayout
定义六个公共可绑定属性以及五个附加的影响其子元素大小、方向和对齐方式的可绑定属性。 (如果不熟悉附加的可绑定属性,请参阅附加属性一文。)下面的“可绑定属性的详细信息”和“附加的可绑定属性的详细信息”部分详细介绍了这些属性。 但是,本文首先介绍了 FlexLayout
的一些常见使用方案部分,以更加非正式的方式描述了其中许多属性。 本文末尾介绍如何将 FlexLayout
与CSS 样式表合并。
常见使用方案
该示例程序包含多个页面,这些页面介绍了 FlexLayout
的一些常见用途,并允许你试验其属性。
将 FlexLayout 用于简单堆栈
简单堆栈页显示 FlexLayout
如何替代 StackLayout
,但使用更简单的标记。 此示例中的所有内容在 XAML 页中定义。 FlexLayout
包含四个子元素:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:FlexLayoutDemos"
x:Class="FlexLayoutDemos.SimpleStackPage"
Title="Simple Stack">
<FlexLayout Direction="Column"
AlignItems="Center"
JustifyContent="SpaceEvenly">
<Label Text="FlexLayout in Action"
FontSize="Large" />
<Image Source="{local:ImageResource FlexLayoutDemos.Images.SeatedMonkey.jpg}" />
<Button Text="Do-Nothing Button" />
<Label Text="Another Label" />
</FlexLayout>
</ContentPage>
下面是在 iOS、Android 和通用 Windows 平台上运行的页面:
SimpleStackPage.xaml 文件中显示了 FlexLayout
的三个属性:
Direction
属性设置为FlexDirection
枚举的值。 默认为Row
。 将属性设置为Column
会导致FlexLayout
的子元素排列在单个项列中。当
FlexLayout
中的项排列在列中时,FlexLayout
被认为有垂直主轴和水平交叉轴。AlignItems
属性的类型为FlexAlignItems
,并指定项在十字轴上对齐的方式。Center
选项会导致每个项水平居中。如果对此任务使用
StackLayout
而不是FlexLayout
,则通过将每个项的HorizontalOptions
属性分配给Center
来使所有项居中。HorizontalOptions
属性不适用于FlexLayout
的子元素,但单个AlignItems
属性可实现相同的目标。 如果需要,可以使用AlignSelf
附加的可绑定属性替代各个项的AlignItems
属性:<Label Text="FlexLayout in Action" FontSize="Large" FlexLayout.AlignSelf="Start" />
更改后,当阅读顺序从左到右时,此
Label
位于FlexLayout
的左边缘。JustifyContent
属性的类型为FlexJustify
,并指定项目在主轴上的排列方式。SpaceEvenly
选项在所有项之间以及第一个项上方和最后一个项下方分配所有剩余的垂直空间。如果使用
StackLayout
,则需要将每个项的VerticalOptions
属性分配给CenterAndExpand
才可达到类似的效果。 但是,CenterAndExpand
选项会为每个项之间分配两倍于第一个项之前和最后一个项之后的空间。 通过将FlexLayout
的JustifyContent
属性设置为SpaceAround
,可以模拟VerticalOptions
的CenterAndExpand
选项。
下面的“可绑定属性”部分详细讨论这些 FlexLayout
属性。
使用 FlexLayout 包装项
示例的“照片包装”页面演示了 FlexLayout
如何将其子级包装到其他行或列。 XAML 文件实例化 FlexLayout
并为其分配两个属性:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="FlexLayoutDemos.PhotoWrappingPage"
Title="Photo Wrapping">
<Grid>
<ScrollView>
<FlexLayout x:Name="flexLayout"
Wrap="Wrap"
JustifyContent="SpaceAround" />
</ScrollView>
<ActivityIndicator x:Name="activityIndicator"
IsRunning="True"
VerticalOptions="Center" />
</Grid>
</ContentPage>
此 FlexLayout
的 Direction
属性未设置,因此它具有默认设置 Row
,这意味着子元素按行排列,主轴是水平的。
Wrap
属性是枚举类型 FlexWrap
。 如果行上容纳的项目太多,则此属性设置会导致项换行到下一行。
请注意,FlexLayout
是 ScrollView
的子元素。 如果页面上的行太多,则 ScrollView
具有 Vertical
的默认 Orientation
属性并允许垂直滚动。
JustifyContent
属性在主轴(水平轴)上分配剩余空间,以便每个项被相同数量的空白空间包围。
代码隐藏文件访问示例照片的集合,并将其添加到 FlexLayout
的 Children
集合:
public partial class PhotoWrappingPage : ContentPage
{
// Class for deserializing JSON list of sample bitmaps
[DataContract]
class ImageList
{
[DataMember(Name = "photos")]
public List<string> Photos = null;
}
public PhotoWrappingPage ()
{
InitializeComponent ();
LoadBitmapCollection();
}
async void LoadBitmapCollection()
{
using (WebClient webClient = new WebClient())
{
try
{
// Download the list of stock photos
Uri uri = new Uri("https://raw.githubusercontent.com/xamarin/docs-archive/master/Images/stock/small/stock.json");
byte[] data = await webClient.DownloadDataTaskAsync(uri);
// Convert to a Stream object
using (Stream stream = new MemoryStream(data))
{
// Deserialize the JSON into an ImageList object
var jsonSerializer = new DataContractJsonSerializer(typeof(ImageList));
ImageList imageList = (ImageList)jsonSerializer.ReadObject(stream);
// Create an Image object for each bitmap
foreach (string filepath in imageList.Photos)
{
Image image = new Image
{
Source = ImageSource.FromUri(new Uri(filepath))
};
flexLayout.Children.Add(image);
}
}
}
catch
{
flexLayout.Children.Add(new Label
{
Text = "Cannot access list of bitmap files"
});
}
}
activityIndicator.IsRunning = false;
activityIndicator.IsVisible = false;
}
}
下面是正在运行的程序,从上到下逐步滚动:
使用 FlexLayout 的页面布局
Web 设计中有一个名为“圣杯”的标准布局,因为它是一种非常理想的布局格式,但通常很难完美实现。 布局由页面顶部的页眉和底部的页脚组成,两者都延伸到页面的整个宽度。 占据页面中心的是主要内容,但通常在内容左侧有列式菜单,右侧为补充信息(有时称为侧边栏区域)。 CSS 灵活框布局规范的第 5.4.1 节介绍了如何使用弹性框实现神圣的三位一体布局。
示例的“圣杯布局”页面显示了此布局的一个简单实现,其中使用了一个嵌套在另一个 FlexLayout
中的 FlexLayout。 由于此页面专为纵向模式下的手机设计,内容区域左侧和右侧的区域宽度仅为 50 像素:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="FlexLayoutDemos.HolyGrailLayoutPage"
Title="Holy Grail Layout">
<FlexLayout Direction="Column">
<!-- Header -->
<Label Text="HEADER"
FontSize="Large"
BackgroundColor="Aqua"
HorizontalTextAlignment="Center" />
<!-- Body -->
<FlexLayout FlexLayout.Grow="1">
<!-- Content -->
<Label Text="CONTENT"
FontSize="Large"
BackgroundColor="Gray"
HorizontalTextAlignment="Center"
VerticalTextAlignment="Center"
FlexLayout.Grow="1" />
<!-- Navigation items-->
<BoxView FlexLayout.Basis="50"
FlexLayout.Order="-1"
Color="Blue" />
<!-- Aside items -->
<BoxView FlexLayout.Basis="50"
Color="Green" />
</FlexLayout>
<!-- Footer -->
<Label Text="FOOTER"
FontSize="Large"
BackgroundColor="Pink"
HorizontalTextAlignment="Center" />
</FlexLayout>
</ContentPage>
此处它正在运行:
导航和侧边栏区域通过 BoxView
呈现在左右两侧。
XAML 文件中的第一个 FlexLayout
有一个垂直主轴,并且包含三个在列中排列的子元素。 它们是页眉、页面正文和页脚。 嵌套的 FlexLayout
有一个水平主轴,其中三个子元素在一行。
此程序演示了三个附加的可绑定属性:
Order
附加的可绑定属性放在第一个BoxView
上。 此属性是默认值为 0 的整数。 可以使用此属性更改布局顺序。 通常,开发人员更喜欢页面的内容显示在导航项和项旁的标记中。 将第一个BoxView
上的Order
属性设置为小于其他同级的值会导致它显示为行中的第一项。 同样,可以通过将Order
属性设置为大于其同级的值来确保项最后显示。Basis
附加的可绑定属性在两个BoxView
项上设置,使其宽度为 50 像素。 此属性的类型为FlexBasis
,该结构定义名为Auto
的FlexBasis
类型静态属性,这是默认值。 可以使用Basis
指定像素大小或百分比,指示项在主轴上占用的空间。 它称为基础,因为它指定项大小,是所有后续布局的基础。Grow
属性在嵌套的Layout
和表示内容的Label
子元素上设置。 此属性的类型为float
,默认值为 0。 当设置为正值时,沿主轴的所有剩余空间将分配给该项以及具有正值Grow
的同级。 空间按比例分配给值,有点像Grid
中的星形规范。第一个
Grow
附加属性在嵌套的FlexLayout
上设置,指示此FlexLayout
将占用外部FlexLayout
内所有未使用的垂直空间。 第二个Grow
附加属性在表示内容的Label
上设置,指示此内容将占用内部FlexLayout
内所有未使用的水平空间。还有一个类似的
Shrink
附加的可绑定属性,当子级的大小超过FlexLayout
的大小但不需要包装时,可以使用此属性。
带 FlexLayout 的目录项
示例中的“目录项”页面类似于 CSS 弹性布局框规范第 1.1 节中的 示例 1,只不过它显示了三只猴子的水平滚动系列图片和说明:
在这三只猴子中,每只都是一个 FlexLayout
,包含在具有明确高度和宽度的 Frame
中,同时也是更大 FlexLayout
的子元素。 在此 XAML 文件中,FlexLayout
子元素的大多数属性都以样式指定,但其中一个属性是隐式样式:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:FlexLayoutDemos"
x:Class="FlexLayoutDemos.CatalogItemsPage"
Title="Catalog Items">
<ContentPage.Resources>
<Style TargetType="Frame">
<Setter Property="BackgroundColor" Value="LightYellow" />
<Setter Property="BorderColor" Value="Blue" />
<Setter Property="Margin" Value="10" />
<Setter Property="CornerRadius" Value="15" />
</Style>
<Style TargetType="Label">
<Setter Property="Margin" Value="0, 4" />
</Style>
<Style x:Key="headerLabel" TargetType="Label">
<Setter Property="Margin" Value="0, 8" />
<Setter Property="FontSize" Value="Large" />
<Setter Property="TextColor" Value="Blue" />
</Style>
<Style TargetType="Image">
<Setter Property="FlexLayout.Order" Value="-1" />
<Setter Property="FlexLayout.AlignSelf" Value="Center" />
</Style>
<Style TargetType="Button">
<Setter Property="Text" Value="LEARN MORE" />
<Setter Property="FontSize" Value="Large" />
<Setter Property="TextColor" Value="White" />
<Setter Property="BackgroundColor" Value="Green" />
<Setter Property="BorderRadius" Value="20" />
</Style>
</ContentPage.Resources>
<ScrollView Orientation="Both">
<FlexLayout>
<Frame WidthRequest="300"
HeightRequest="480">
<FlexLayout Direction="Column">
<Label Text="Seated Monkey"
Style="{StaticResource headerLabel}" />
<Label Text="This monkey is laid back and relaxed, and likes to watch the world go by." />
<Label Text=" • Doesn't make a lot of noise" />
<Label Text=" • Often smiles mysteriously" />
<Label Text=" • Sleeps sitting up" />
<Image Source="{local:ImageResource FlexLayoutDemos.Images.SeatedMonkey.jpg}"
WidthRequest="180"
HeightRequest="180" />
<Label FlexLayout.Grow="1" />
<Button />
</FlexLayout>
</Frame>
<Frame WidthRequest="300"
HeightRequest="480">
<FlexLayout Direction="Column">
<Label Text="Banana Monkey"
Style="{StaticResource headerLabel}" />
<Label Text="Watch this monkey eat a giant banana." />
<Label Text=" • More fun than a barrel of monkeys" />
<Label Text=" • Banana not included" />
<Image Source="{local:ImageResource FlexLayoutDemos.Images.Banana.jpg}"
WidthRequest="240"
HeightRequest="180" />
<Label FlexLayout.Grow="1" />
<Button />
</FlexLayout>
</Frame>
<Frame WidthRequest="300"
HeightRequest="480">
<FlexLayout Direction="Column">
<Label Text="Face-Palm Monkey"
Style="{StaticResource headerLabel}" />
<Label Text="This monkey reacts appropriately to ridiculous assertions and actions." />
<Label Text=" • Cynical but not unfriendly" />
<Label Text=" • Seven varieties of grimaces" />
<Label Text=" • Doesn't laugh at your jokes" />
<Image Source="{local:ImageResource FlexLayoutDemos.Images.FacePalm.jpg}"
WidthRequest="180"
HeightRequest="180" />
<Label FlexLayout.Grow="1" />
<Button />
</FlexLayout>
</Frame>
</FlexLayout>
</ScrollView>
</ContentPage>
Image
的隐式样式包括 Flexlayout
两个附加的可绑定属性的设置:
<Style TargetType="Image">
<Setter Property="FlexLayout.Order" Value="-1" />
<Setter Property="FlexLayout.AlignSelf" Value="Center" />
</Style>
Order
设置 –1 会导致 Image
元素首先显示在每个嵌套的 FlexLayout
视图中,而不考虑其在子集合中的位置。 Center
的 AlignSelf
属性会导致 Image
在 FlexLayout
内居中。 这将替代 AlignItems
属性的设置,默认值为 Stretch
,意味着 Label
和 Button
子元素拉伸到 FlexLayout
的全宽。
在三个 FlexLayout
视图的每个视图中,一个空白 Label
位于 Button
前面,但它的 Grow
设置为 1。 这意味着,所有额外的垂直空间都分配给此空白 Label
,从而有效地将 Button
推送到底部。
可绑定属性的详细信息
现在,你已经知道了 FlexLayout
一些常见的应用,接下可以更详细地探索 FlexLayout
的属性。
FlexLayout
定义在代码或 XAML 中 FlexLayout
本身上设置的六个可绑定属性,以控制方向和对齐方式。 (本文未介绍其中一个属性:Position
。)
你可以使用示例的“试验”页面来试验剩余的可绑定属性。 通过此页面,可以从 FlexLayout
添加或删除子元素,并设置五个可绑定属性的组合。 FlexLayout
的所有子元素都是不同颜色和大小的 Label
视图,Text
属性设置为与其在 Children
集合中的位置对应的数字。
当程序启动时,五个 Picker
视图显示这五个 FlexLayout
属性的默认值。 屏幕底部的 FlexLayout
包含三个子元素:
每个 Label
视图都有一个灰色背景,显示分配给 FlexLayout
内该 Label
的空间。 FlexLayout
本身的背景是 Alice Blue。 它占据页面的整个底部区域,左侧和右侧还有一点边距。
Direction 属性
Direction
属性的类型为 FlexDirection
,是一个具有四个成员的枚举:
Column
ColumnReverse
(或 XAML 中的 "column-reverse")Row
(默认值)RowReverse
(或 XAML 中的 "row-reverse")
在 XAML 中,可以使用小写、大写或混合大小写的枚举成员名称指定此属性的值,也可以使用括号中显示的两个额外的字符串,这些字符串与 CSS 指示符相同。 (在 XAML 分析器使用的 FlexDirectionTypeConverter
类中定义 "column-reverse" 和 "row-reverse" 字符串。)
下面是显示(从左到右)、Row
方向、Column
方向和 ColumnReverse
方向的 试验 页:
请注意,对于 Reverse
选项,项从右侧或底部开始。
Wrap 属性
Wrap
属性的类型为 FlexWrap
,是一个具有三个成员的枚举:
NoWrap
(默认值)Wrap
Reverse
(或 XAML 中的 "wrap-reverse")
从左到右,这些屏幕显示 12 个子元素的 NoWrap
、Wrap
和 Reverse
选项:
当 Wrap
属性设置为 NoWrap
并且主轴受到约束(如此程序所示),并且主轴宽度或高到足以容纳所有子元素时,FlexLayout
会尝试使项更小,如 iOS 屏幕截图所示。 可以使用 Shrink
附加的可绑定属性控制项的收缩。
JustifyContent 属性
JustifyContent
属性的类型为 FlexJustify
,是一个具有六个成员的枚举:
Start
(或 XAML 中的 "flex-start"),默认值Center
End
(或 XAML 中的 "flex-end")SpaceBetween
(或 XAML 中的 "space-between")SpaceAround
(或 XAML 中的 "space-around")SpaceEvenly
此属性指定在主轴上分隔项的方式,在本示例中是水平轴:
在这三个屏幕截图中,Wrap
属性设置为 Wrap
。 Start
默认值显示在之前的 Android 屏幕截图中。 此处的 iOS 屏幕截图显示了 Center
选项:所有项都移动到中心。 以字 Space
开头的三个选项分配项未占用的额外空间。 SpaceBetween
在项之间分配相等的空间;SpaceAround
在每个项周围放置相等的空间,而 SpaceEvenly
在每个项之间以及行上第一项之前和最后一项之后放置相等的空间。
AlignItems 属性
AlignItems
属性的类型为 FlexAlignItems
,是一个具有四个成员的枚举:
Stretch
(默认值)Center
Start
(或 XAML 中的 "flex-start")End
(或 XAML 中的 "flex-end")
这是两个属性之一(另一个是 AlignContent
),指示子元素如何在十字轴上对齐。 在每个行中,子元素将拉伸(如上一屏幕截图所示),或在每个项的开始、中心或末尾对齐,如以下三个屏幕截图所示:
在 iOS 屏幕截图中,所有子元素的顶部都对齐。 在 Android 屏幕截图中,项目垂直居中,以最高的子元素为基础。 在 UWP 屏幕截图中,所有项的底部都对齐。
对于任何单个项,可以使用附加的可绑定属性 AlignSelf
替代 AlignItems
设置。
AlignContent 属性
AlignContent
属性的类型为 FlexAlignContent
,是一个具有七个成员的枚举:
Stretch
(默认值)Center
Start
(或 XAML 中的 "flex-start")End
(或 XAML 中的 "flex-end")SpaceBetween
(或 XAML 中的 "space-between")SpaceAround
(或 XAML 中的 "space-around")SpaceEvenly
与 AlignItems
一样,AlignContent
属性也会对齐十字轴上的子元素,但会影响整个行或列:
在 iOS 屏幕截图中,两行都位于顶部;在 Android 屏幕截图中,它们位于中心;在 UWP 屏幕截图中位于底部。 也可用多种方式分隔行:
当只有一行或一列时,AlignContent
不起作用。
附加的可绑定属性的详细信息
FlexLayout
定义五个附加的可绑定属性。 这些属性在 FlexLayout
的子元素上设置,仅与该特定子元素相关。
AlignSelf 属性
AlignSelf
附加的可绑定属性的类型为 FlexAlignSelf
,是一个具有五个成员的枚举:
Auto
(默认值)Stretch
Center
Start
(或 XAML 中的 "flex-start")End
(或 XAML 中的 "flex-end")
对于 FlexLayout
的任何单个子元素,此属性设置将替代 FlexLayout
本身上设置的 AlignItems
属性。 Auto
的默认设置是指使用 AlignItems
设置。
对于名为 label
(或示例)的 Label
元素,可以在代码中设置 AlignSelf
属性,如下所示:
FlexLayout.SetAlignSelf(label, FlexAlignSelf.Center);
请注意,没有引用 Label
的 FlexLayout
父级。 在 XAML 中,设置如下属性:
<Label ... FlexLayout.AlignSelf="Center" ... />
Order 属性
Order
属性为 int
类型。 默认值为 0。
使用 Order
属性可以更改 FlexLayout
子元素的排列顺序。 通常,FlexLayout
子元素的排列顺序与 Children
集合中显示的顺序相同。 可以通过在一个或多个子元素上将 Order
附加的可绑定属性设置为非零整数值来替代此顺序。 然后,FlexLayout
根据每个子元素的 Order
属性设置来排列其子元素,但具有相同 Order
设置的子元素按它们在 Children
集合中显示的顺序排列。
Basis 属性
Basis
附加的可绑定属性指示分配给主轴上 FlexLayout
子元素的空间量。 由 Basis
属性指定的大小是父级 FlexLayout
的主轴上的大小。 因此,Basis
指示子元素的宽度(当子元素按行排列时)或高度(当子元素按列排列时)。
Basis
属性的类型为 FlexBasis
,是一种结构。 可以用与设备无关的单位指定大小,也可以指定为 FlexLayout
大小的百分比。 Basis
属性的默认值是静态属性 FlexBasis.Auto
,这意味着使用了子元素请求的宽度或高度。
在代码中,可以将名为 label
的 Label
的 Basis
属性设置为 40 个独立于设备的单元,如下所示:
FlexLayout.SetBasis(label, new FlexBasis(40, false));
FlexBasis
构造函数的第二个参数以 isRelative
命名,并指示大小是相对 (true
) 还是绝对 (false
)。 该参数的默认值为 false
,因此也可以使用以下代码:
FlexLayout.SetBasis(label, new FlexBasis(40));
定义了从 float
到 FlexBasis
的隐式转换,因此可以进一步简化它:
FlexLayout.SetBasis(label, 40);
可以将 FlexLayout
父级的大小设置为 25%,如下所示:
FlexLayout.SetBasis(label, new FlexBasis(0.25f, true));
此小数部分值必须介于 0 到 1 的范围内。
在 XAML 中,可以使用设备无关单位以数字表示大小:
<Label ... FlexLayout.Basis="40" ... />
或者,可以在 0% 到 100% 的范围内指定百分比:
<Label ... FlexLayout.Basis="25%" ... />
示例的“基础试验”页面让你能够试验 Basis
属性。 该页显示五个具有交替背景和前景颜色的五个 Label
元素的包装列。 使用两个 Slider
元素可为第二和第四个 Label
指定 Basis
值:
左侧的 iOS 屏幕截图以与设备无关的单位显示了两个 Label
元素的高度。 Android 屏幕以 FlexLayout
总高度的比例显示这些高度。 如果 Basis
设置为 100%,则子元素的高度为 FlexLayout
,将换行到下一列并占据该列的整个高度,如 UWP 屏幕截图所示:看起来这五个子元素排列在一行中,但实际上按五列排列的。
Grow 属性
Grow
附加的可绑定属性的类型为 int
。 默认值为 0,该值必须大于或等于 0。
当 Wrap
属性设置为 NoWrap
并且子元素行的总宽度小于 FlexLayout
的宽度,或者子元素的列比 FlexLayout
短时,Grow
属性将发挥作用。 Grow
属性指示如何在子项之间分配剩余空间。
在增长试验页中,五个交替颜色的 Label
元素排列在一列中,两个 Slider
元素允许调整第二个和第四个 Label
的 Grow
属性。 最左侧的 iOS 屏幕截图显示默认 Grow
属性 0:
如果向任何一个子元素提供正 Grow
值,则该子元素将占用所有剩余空间,如 Android 屏幕截图所示。 还可以在两个或以上的个子元素之间分配此空间。 在 UWP 屏幕截图中,第二个 Label
的 Grow
属性设置为 0.5,而第四个 Label
的 Grow
属性为 1.5,第四个 Label
的剩余空间比第二个 Label
多三倍。
子视图使用该空间的方式取决于子元素的特定类型。 对于 Label
,可以使用属性 HorizontalTextAlignment
和 VerticalTextAlignment
将文本放置在 Label
的总空间中。
Shrink 属性
Shrink
附加的可绑定属性的类型为 int
。 默认值为 1,该值必须大于或等于 0。
当 Wrap
属性设置为 NoWrap
且子元素的聚合宽度大于 FlexLayout
的宽度时,或者单个子元素列的聚合高度大于 FlexLayout
的高度时,Shrink
属性将发挥作用。 通常,FlexLayout
会通过限制这些子项的大小以显示它们。 Shrink
属性可以指示哪些子项可优先按其完整大小显示。
收缩试验页创建了一个 FlexLayout
,其中包含一行五个 Label
子元素,所需空间超过 FlexLayout
宽度。 左侧的 iOS 屏幕截图显示默认值为 1 的所有 Label
元素:
在 Android 屏幕截图中,第二个 Label
的 Shrink
值设置为 0,而 Label
以全宽显示。 此外,第四个 Label
的值为大于 1 的 Shrink
值,但已收缩。 UWP 屏幕截图显示两个 Label
元素都给定了 Shrink
值 0,以允许它们以其完整大小显示(如果可能)。
可以同时设置 Grow
值和 Shrink
值,以适应聚合子元素大小有时可能小于或大于 FlexLayout
大小的情况。
使用 FlexLayout 设置 CSS 样式
可以使用与 FlexLayout
相关的 Xamarin.Forms 3.0 引入的 CSS 样式功能。 示例的“CSS 目录项”页面复制了“目录项”页面的布局,但具有许多样式的 CSS 样式表:
原始 CatalogItemsPage.xaml 文件在其具有 15 个 Setter
对象的 Resources
部分中具有五个 Style
定义。 在 CssCatalogItemsPage.xaml 文件中,已减少到只有四个 Setter
对象的两个 Style
定义。 这些样式补充了 Xamarin.Forms CSS 样式设置功能当前不支持的属性的 CSS 样式表:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:FlexLayoutDemos"
x:Class="FlexLayoutDemos.CssCatalogItemsPage"
Title="CSS Catalog Items">
<ContentPage.Resources>
<StyleSheet Source="CatalogItemsStyles.css" />
<Style TargetType="Frame">
<Setter Property="BorderColor" Value="Blue" />
<Setter Property="CornerRadius" Value="15" />
</Style>
<Style TargetType="Button">
<Setter Property="Text" Value="LEARN MORE" />
<Setter Property="BorderRadius" Value="20" />
</Style>
</ContentPage.Resources>
<ScrollView Orientation="Both">
<FlexLayout>
<Frame>
<FlexLayout Direction="Column">
<Label Text="Seated Monkey" StyleClass="header" />
<Label Text="This monkey is laid back and relaxed, and likes to watch the world go by." />
<Label Text=" • Doesn't make a lot of noise" />
<Label Text=" • Often smiles mysteriously" />
<Label Text=" • Sleeps sitting up" />
<Image Source="{local:ImageResource FlexLayoutDemos.Images.SeatedMonkey.jpg}" />
<Label StyleClass="empty" />
<Button />
</FlexLayout>
</Frame>
<Frame>
<FlexLayout Direction="Column">
<Label Text="Banana Monkey" StyleClass="header" />
<Label Text="Watch this monkey eat a giant banana." />
<Label Text=" • More fun than a barrel of monkeys" />
<Label Text=" • Banana not included" />
<Image Source="{local:ImageResource FlexLayoutDemos.Images.Banana.jpg}" />
<Label StyleClass="empty" />
<Button />
</FlexLayout>
</Frame>
<Frame>
<FlexLayout Direction="Column">
<Label Text="Face-Palm Monkey" StyleClass="header" />
<Label Text="This monkey reacts appropriately to ridiculous assertions and actions." />
<Label Text=" • Cynical but not unfriendly" />
<Label Text=" • Seven varieties of grimaces" />
<Label Text=" • Doesn't laugh at your jokes" />
<Image Source="{local:ImageResource FlexLayoutDemos.Images.FacePalm.jpg}" />
<Label StyleClass="empty" />
<Button />
</FlexLayout>
</Frame>
</FlexLayout>
</ScrollView>
</ContentPage>
CSS 样式表在 Resources
部分的第一行中引用:
<StyleSheet Source="CatalogItemsStyles.css" />
另请注意,在这三个项中,每个项的两个元素包括 StyleClass
设置:
<Label Text="Seated Monkey" StyleClass="header" />
···
<Label StyleClass="empty" />
这些引用 CatalogItemsStyles.css 样式表中的选择器:
frame {
width: 300;
height: 480;
background-color: lightyellow;
margin: 10;
}
label {
margin: 4 0;
}
label.header {
margin: 8 0;
font-size: large;
color: blue;
}
label.empty {
flex-grow: 1;
}
image {
height: 180;
order: -1;
align-self: center;
}
button {
font-size: large;
color: white;
background-color: green;
}
此处引用了几个 FlexLayout
附加的可绑定属性。 在 label.empty
选择器中,你将看到 flex-grow
属性,该属性设置空 Label
样式,以在 Button
上方提供一些空白空间。 image
选择器包含 order
属性和 align-self
属性,这两个属性都对应于 FlexLayout
附加的可绑定属性。
你已经了解,可以直接在 FlexLayout
上设置属性,并且可以在 FlexLayout
的子元素上设置附加的可绑定属性。 或者,可以使用传统的基于 XAML 的样式或 CSS 样式间接设置这些属性。 重要的是了解这些属性。 正是这些属性让 FlexLayout
真正变得灵活。
包含 Xamarin.University 的 FlexLayout
Xamarin.Forms 3.0 弹性布局视频