Xamarin.Forms AbsoluteLayout
一个 AbsoluteLayout
用于使用显式值定位和调整子级的大小。 该位置按与设备无关的单位,由相对于 AbsoluteLayout
左上角的子级的左上角指定。 AbsoluteLayout
还实现了按比例定位和调整大小的功能。 此外,与其他一些布局类不同,AbsoluteLayout
能够调整子级的位置,因而子级间可以重叠。
AbsoluteLayout
应视为特殊用途的布局,仅在你可以设置子级的大小或元素的大小不影响其他子级的位置时使用。
AbsoluteLayout
类定义以下属性:
LayoutBounds
,类型为Rectangle
,是附加属性,用于表示子级的位置和大小。 此属性的默认值为 (0,0,AutoSize,AutoSize)。LayoutFlags
,类型为AbsoluteLayoutFlags
,是一个附加属性,指示用于调整子级位置和大小的布局边界的属性是否按比例解读。 此属性的默认值为AbsoluteLayoutFlags.None
。
这些属性由 BindableProperty
对象提供支持,这意味着它们可以作为数据绑定的目标,也可以进行设置样式。 有关附加属性的详细信息,请参阅 Xamarin.Forms 附加属性。
AbsoluteLayout
类派生自 Layout<T>
类,后者定义了类型 IList<T>
的 Children
属性。 由于 Children
属性是 Layout<T>
类的 ContentProperty
,因此不需要通过 XAML 显式设置。
提示
若要获取最佳可能布局性能,请遵循优化布局性能中的准则。
调整子级的位置和大小
通过使用绝对值或比例值设置每个子级的 AbsoluteLayout.LayoutBounds
附加属性来定义 AbsoluteLayout
中子级的位置和大小。 当位置应缩放时,子级的绝对值和比例值可以混用,但大小应保持固定,反之亦然。 有关绝对值的信息,请参阅调整绝对位置和大小。 有关比例值的信息,请参阅按比例调整位置和大小。
无论使用绝对值还是比例值,都可以使用两种格式设置 AbsoluteLayout.LayoutBounds
附加属性:
x, y
。 使用此格式时,x
和y
值指示子级的左上角相对于其父级的位置。 子级不受约束,自行调整大小。x, y, width, height
。 使用此格式时,x
和y
值指示子级的左上角相对于其父级的位置,而width
和height
值指示子级的大小。
要指定子级在水平和/或垂直方式自行调整大小,请将 width
和/或 height
值设置为 AbsoluteLayout.AutoSize
属性。 但是,过度使用此属性可能会损害应用程序性能,因为会导致布局引擎执行额外的布局计算。
重要
HorizontalOptions
和 VerticalOptions
属性对 AbsoluteLayout
的子级不起作用。
调整绝对位置和大小
默认情况下,AbsoluteLayout
会按与设备无关的单位,使用绝对值调整子级的位置和大小,该单位显式定义了子级应在布局中放置的位置。 实现此目的的方法是,将子级添加到 AbsoluteLayout
的 Children
集合,并将每个子级的 AbsoluteLayout.LayoutBounds
附加属性设置为绝对位置和/或大小值。
警告
使用绝对值调整子级的位置和大小可能会出问题,因为不同设备的屏幕大小和分辨率也不同。 因此,一台设备上的屏幕中心坐标在其他设备上可能会出现偏移。
以下 XAML 显示了使用绝对值调整子级位置的 AbsoluteLayout
:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="AbsoluteLayoutDemos.Views.StylishHeaderDemoPage"
Title="Stylish header demo">
<AbsoluteLayout Margin="20">
<BoxView Color="Silver"
AbsoluteLayout.LayoutBounds="0, 10, 200, 5" />
<BoxView Color="Silver"
AbsoluteLayout.LayoutBounds="0, 20, 200, 5" />
<BoxView Color="Silver"
AbsoluteLayout.LayoutBounds="10, 0, 5, 65" />
<BoxView Color="Silver"
AbsoluteLayout.LayoutBounds="20, 0, 5, 65" />
<Label Text="Stylish Header"
FontSize="24"
AbsoluteLayout.LayoutBounds="30, 25" />
</AbsoluteLayout>
</ContentPage>
在此示例中,使用 AbsoluteLayout.LayoutBounds
附加属性中指定的前两个绝对值来定义每个 BoxView
对象的位置。 每个 BoxView
的大小是使用第三个和第四个值定义的。 Label
对象的位置是使用 AbsoluteLayout.LayoutBounds
附加属性中指定的两个绝对值定义的。 没有为 Label
指定大小值,因此其大小不受约束并可自行调整。 在所有情况下,绝对值都表示与设备无关的单位。
以下屏幕截图显示了生成的布局:
等效 C# 代码如下所示:
public class StylishHeaderDemoPageCS : ContentPage
{
public StylishHeaderDemoPageCS()
{
AbsoluteLayout absoluteLayout = new AbsoluteLayout
{
Margin = new Thickness(20)
};
absoluteLayout.Children.Add(new BoxView
{
Color = Color.Silver,
}, new Rectangle(0, 10, 200, 5));
absoluteLayout.Children.Add(new BoxView
{
Color = Color.Silver
}, new Rectangle(0, 20, 200, 5));
absoluteLayout.Children.Add(new BoxView
{
Color = Color.Silver
}, new Rectangle(10, 0, 5, 65));
absoluteLayout.Children.Add(new BoxView
{
Color = Color.Silver
}, new Rectangle(20, 0, 5, 65));
absoluteLayout.Children.Add(new Label
{
Text = "Stylish Header",
FontSize = 24
}, new Point(30,25));
Title = "Stylish header demo";
Content = absoluteLayout;
}
}
在此示例中,每个 BoxView
的位置和大小都是使用 Rectangle
对象定义的。 使用 Point
对象定义 Label
的位置。
在 C# 中,还可以使用 AbsoluteLayout.SetLayoutBounds
方法将 AbsoluteLayout
的子级添加到 Children
集合后设置其位置和大小。 此方法的第一个参数是子级,第二个参数是 Rectangle
对象。
注意
使用绝对值的 AbsoluteLayout
可以调整子级的位置和大小,使它们不再固定在布局的边界之中。
按比例调整位置和大小
AbsoluteLayout
可以使用比例值来调整子级的位置和大小。 实现方式是,将子级添加到 AbsoluteLayout
的 Children
集合,并将每个子级的 AbsoluteLayout.LayoutBounds
附加属性设置为 0-1 范围内的成比例位置和/或大小值。 通过在每个子级上设置 AbsoluteLayout.LayoutFlags
附加属性,使位置值和大小值成比例。
AbsoluteLayoutFlags
类型的 AbsoluteLayout.LayoutFlags
附加属性允许你设置一个标记,该标志指示子级的布局边界位置和大小值与 AbsoluteLayout
的大小成比例。 对子级进行布局时,AbsoluteLayout
会将位置和大小值相应地缩放以匹配任何设备的大小。
AbsoluteLayoutFlags
枚举定义以下成员:
None
表示这些值将被解释为绝对值。 这是附加属性AbsoluteLayout.LayoutFlags
的默认值。XProportional
表示x
值将被解释为比例值,同时将所有其他值视为绝对值。YProportional
表示y
值将被解释为比例值,同时将所有其他值视为绝对值。WidthProportional
表示width
值将被解释为比例值,同时将所有其他值视为绝对值。HeightProportional
表示height
值将被解释为比例值,同时将所有其他值视为绝对值。PositionProportional
表示x
和y
值将被解释为比例值,而大小值则被解释为绝对值。SizeProportional
表示width
和height
值将被解释为比例值,而定位值则被解释为绝对值。All
表示所有值都将被解释为比例值。
提示
AbsoluteLayoutFlags
枚举是 Flags
枚举,这意味着可以组合枚举成员。 这在 XAML 中是通过逗号分隔的列表实现的,在 C# 中是通过按位 OR 运算符实现的。
例如,如果使用 SizeProportional
标记并将子级的宽度设置为 0.25,高度设置为 0.1,则子级将是 AbsoluteLayout
宽度的四分之一和高度的十分之一。 PositionProportional
标记与此类似。 位置 (0,0) 将子级置于左上角,而位置 (1,1) 将子级置于右下角,位置 (0.5,0.5) 将子级置于 AbsoluteLayout
的中心。
以下 XAML 显示其子级使用比例值定位的 AbsoluteLayout
:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="AbsoluteLayoutDemos.Views.ProportionalDemoPage"
Title="Proportional demo">
<AbsoluteLayout>
<BoxView Color="Blue"
AbsoluteLayout.LayoutBounds="0.5,0,100,25"
AbsoluteLayout.LayoutFlags="PositionProportional" />
<BoxView Color="Green"
AbsoluteLayout.LayoutBounds="0,0.5,25,100"
AbsoluteLayout.LayoutFlags="PositionProportional" />
<BoxView Color="Red"
AbsoluteLayout.LayoutBounds="1,0.5,25,100"
AbsoluteLayout.LayoutFlags="PositionProportional" />
<BoxView Color="Black"
AbsoluteLayout.LayoutBounds="0.5,1,100,25"
AbsoluteLayout.LayoutFlags="PositionProportional" />
<Label Text="Centered text"
AbsoluteLayout.LayoutBounds="0.5,0.5,110,25"
AbsoluteLayout.LayoutFlags="PositionProportional" />
</AbsoluteLayout>
</ContentPage>
在此示例中,每个子对象将使用比例值来定位,但使用绝对值来调整大小。 这是通过将每个子级的 AbsoluteLayout.LayoutFlags
附加属性设置为 PositionProportional
来实现的。 在 AbsoluteLayout.LayoutBounds
附加属性中为每个子级指定的前两个值将使用比例值定义位置。 每个子级的大小由第三个和第四个绝对值定义,使用的是与设备无关的单位。
以下屏幕截图显示了生成的布局:
等效 C# 代码如下所示:
public class ProportionalDemoPageCS : ContentPage
{
public ProportionalDemoPageCS()
{
BoxView blue = new BoxView { Color = Color.Blue };
AbsoluteLayout.SetLayoutBounds(blue, new Rectangle(0.5, 0, 100, 25));
AbsoluteLayout.SetLayoutFlags(blue, AbsoluteLayoutFlags.PositionProportional);
BoxView green = new BoxView { Color = Color.Green };
AbsoluteLayout.SetLayoutBounds(green, new Rectangle(0, 0.5, 25, 100));
AbsoluteLayout.SetLayoutFlags(green, AbsoluteLayoutFlags.PositionProportional);
BoxView red = new BoxView { Color = Color.Red };
AbsoluteLayout.SetLayoutBounds(red, new Rectangle(1, 0.5, 25, 100));
AbsoluteLayout.SetLayoutFlags(red, AbsoluteLayoutFlags.PositionProportional);
BoxView black = new BoxView { Color = Color.Black };
AbsoluteLayout.SetLayoutBounds(black, new Rectangle(0.5, 1, 100, 25));
AbsoluteLayout.SetLayoutFlags(black, AbsoluteLayoutFlags.PositionProportional);
Label label = new Label { Text = "Centered text" };
AbsoluteLayout.SetLayoutBounds(label, new Rectangle(0.5, 0.5, 110, 25));
AbsoluteLayout.SetLayoutFlags(label, AbsoluteLayoutFlags.PositionProportional);
Title = "Proportional demo";
Content = new AbsoluteLayout
{
Children = { blue, green, red, black, label }
};
}
}
在此示例中,每个子级的位置和大小将使用 AbsoluteLayout.SetLayoutBounds
方法设置。 该方法的第一个参数是子级,第二个参数是 Rectangle
对象。 每个子级的位置将用比例值设置,而每个子项的大小将用绝对值设置,使用与设备无关的单位。
注意
使用比例值的 AbsoluteLayout
可以通过使用 0-1 范围之外的值来调整子级的位置和大小,使它们不在布局的边界内。