指定视图大小
设计在各种设备上一致的用户界面非常困难,因为设备具有不同大小和不同的像素密度。 试想不同的可用设备:手机、平板电脑、桌面设备等。 如何创建在每个设备上看起来相似的用户界面?
.NET MAUI 提供有助于生成一致的用户界面的版式面板。 布局面板负责调整其子级视图的大小和位置。 在本单元中,你将了解布局系统如何在 .NET MAUI 中运作。 具体而言,我们将了解默认情况下视图的大小调整方式,以及如何在运行时请求视图的特定大小和位置。
什么是版式面板?
版式面板是一种 .NET MAUI 容器,包含子视图的集合并决定子视图的大小和位置。 应用大小更改时,版式面板会自动进行重新计算;例如,用户旋转设备时。
注意
术语“视图”或“子视图”是指放置在版式面板上的控件。 视图可以是标签、按钮、输入字段或 .NET MAUI 支持的任何其他类型的视觉元素。
.NET MAUI 具有可供选择的多个版式面板。 每个面板以不同的方式管理其子视图。 下图显示了一些最常见选项的概念性概述。
StackLayout
:将其子视图排列在单个行或列中。 除了StackLayout
之外,在不需要更改方向时,还有经优化的新VerticalStackLayout
和HorizontalStackLayout
。AbsoluteLayout
:使用 x 和 y 坐标排列其子视图。Grid
:在从行和列的交集创建的单元格中排列其子视图。FlexLayout
:像StackLayout
一样排列其子视图,只不过在这些子视图不适合单个行或列时可以包装它们。
注意
还有第五种类型的版式面板,称为 RelativeLayout
,它使你能够指定如何相对地排列子视图。 应使用 FlexLayout
控件而不是 RelativeLayout
,因为它的性能更好。 RelativeLayout
包含在 .NET MAUI 中,以便向后兼容较旧的 Xamarin 应用。
生成 .NET MAUI 页面的典型过程是创建版式面板,然后向其添加子视图。 将视图添加到布局时,操作者可影响其大小和位置。 但是,面板根据其内部布局算法具有最终设置权限。
在考虑如何请求视图的特定大小之前,让我们先看看默认情况下布局系统如何调整视图的大小。
视图的默认大小
如果未指定视图的大小,它将自动增加到足以容纳其内容的大小。 例如,请考虑此 XAML:
<Label
Text="Hello"
BackgroundColor="Silver"
VerticalOptions="Center"
HorizontalOptions="Center"
FontSize="40"/>
本示例定义用于在银色背景上显示单词 Hello
的标签。 由于未指定大小,标签会自动调整大小以围绕单词 Hello
。 下图显示了 Android 设备上呈现的标签:
注意
可以设置标签的背景色,以确定标签在运行时的大小。 在生成 UI 时,请记得这是一种不错的调试方法。
指定视图大小
生成 UI 时,通常希望能控制视图的大小。 例如,假设要生成登录页面,并希望登录按钮正好是屏幕宽度的一半。 如果使用的是默认的视图大小调整方式,则按钮大小仅为文本“登录”的大小。 该大小不够大,因此你需要自行指定大小。
View
基类定义影响视图大小的两个属性:WidthRequest
和 HeightRequest
。 通过 WidthRequest
可指定宽度,通过 HeightRequest
可指定高度。 两个属性的类型都是 double
。
以下示例显示如何通过 XAML 指定标签的宽度和高度:
<Label
Text="Hello"
BackgroundColor="Silver"
VerticalOptions="Center"
HorizontalOptions="Center"
WidthRequest="100"
HeightRequest="300"
FontSize="40"/>
结果类似以下形式:
注意
尽管标签的文本不在标签的中心,但标签仍然居中。
值得注意的一点是这些属性的名称。 两个属性都包含“请求”一词。 该词表示版式面板可能不会在运行时应用它们。 版式面板在大小调整计算期间读取这些值,并尝试满足这些请求(如果可以)。 如果没有足够的空间,版式面板可以忽略这些值。
尺寸单位
设置 WidthRequest
和 HeightRequest
时,使用类似于 100
的文本值。 在 .NET MAUI 级别,这些值没有单位。 它们不是点或像素。 它们只是 double
类型的值。 .NET MAUI 在运行时将这些值传递到基础操作系统。 操作系统提供确定数字含义所需的上下文:
- 在 iOS 上,这些值称为“点”。
- 在 Android 上,它们是“与密度无关的像素”。
所呈现的视图大小
因为是由版式面板确定视图的大小,所以无法使用 WidthRequest
和 HeightRequest
在运行时指示实际大小。 例如,假设为标签将 WidthRequest
设置为 100
,但是面板没有足够的控件来满足该请求。 面板会为标签提供宽度 80
。 此时,如果你查看 WidthRequest
属性值的话,你会看到 100
,虽然呈现的值为 80
。
若要解决此问题,View
基类需定义其他两个名为 Width
和 Height
的属性。 这些属性的类型是 double
,表示所呈现的视图宽度和高度。 无论何时检索视图的大小,都使用 Width
和 Height
属性。
指定视图的位置
此外,需要设置视图位置。 例如,回想一下,在登录页面示例中,你希望将登录按钮的大小调整为屏幕宽度的一半。 由于登录按钮的宽度不到屏幕的整个宽度,因此有其他剩余空间,可将其进行移动。 可以将其放置在屏幕左边、右边或中心。
View
基类具有用于设置视图位置的两个属性:VerticalOptions
和 HorizontalOptions
。 这些设置会影响视图在版式面板为其分配的矩形内的位置。 可以将视图指定与矩形的四条边之一对齐。 或者,可以让视图占据整个矩形。
指定 VerticalOptions
或 HorizontalOptions
的值比设置大小更难,因为它们的类型是 LayoutOptions
。
什么是 LayoutOptions 类型?
LayoutOptions
为 C# 类型,包含两个布局首选项:Alignment
和 Expands
。 这两个属性与位置相关,但它们彼此不相关。 类型的定义如下所示:
public struct LayoutOptions
{
public LayoutAlignment Alignment { get; set; }
public bool Expands { get; set; }
...
}
接下来,我们更详细地了解 Alignment
,因为它是最常用且最直观的布局选项。
什么是 LayoutAlignment 枚举?
LayoutAlignment
是包含四个值的枚举:Start
、Center
、End
和 Fill
。 可以使用这些值来控制子视图在版式面板为其提供的矩形内的位置。 以下面的代码和 Android 屏幕截图为例:
<StackLayout>
<Label Text="Start" HorizontalOptions="Start" BackgroundColor="Silver" FontSize="40" />
<Label Text="Center" HorizontalOptions="Center" BackgroundColor="Silver" FontSize="40" />
<Label Text="End" HorizontalOptions="End" BackgroundColor="Silver" FontSize="40"/>
<Label Text="Fill" HorizontalOptions="Fill" BackgroundColor="Silver" FontSize="40"/>
</StackLayout>
该示例使用的是垂直 StackLayout
,因此每个子视图都有一行。 HorizontalOptions
确定视图在其行内的位置。
什么是 Expands?
LayoutOptions
结构的第二个属性是 Expands
。 Expands
属性是 bool
,在 Xamarin.forms 中使 StackLayout
中的视图能够请求额外的空间(如果有)。 此属性现已过时,.NET MAUI 中不再使用。 稍后,我们将了解如何在 Grid
布局的单元中实现相同类型的扩展。