Xamarin.Forms AbsoluteLayout

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。 使用此格式时,xy 值指示子级的左上角相对于其父级的位置。 子级不受约束,自行调整大小。
  • x, y, width, height。 使用此格式时,xy 值指示子级的左上角相对于其父级的位置,而 widthheight 值指示子级的大小。

要指定子级在水平和/或垂直方式自行调整大小,请将 width 和/或 height 值设置为 AbsoluteLayout.AutoSize 属性。 但是,过度使用此属性可能会损害应用程序性能,因为会导致布局引擎执行额外的布局计算。

重要

HorizontalOptionsVerticalOptions 属性对 AbsoluteLayout 的子级不起作用。

调整绝对位置和大小

默认情况下,AbsoluteLayout 会按与设备无关的单位,使用绝对值调整子级的位置和大小,该单位显式定义了子级应在布局中放置的位置。 实现此目的的方法是,将子级添加到 AbsoluteLayoutChildren 集合,并将每个子级的 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 指定大小值,因此其大小不受约束并可自行调整。 在所有情况下,绝对值都表示与设备无关的单位。

以下屏幕截图显示了生成的布局:

使用绝对值放置在 AbsoluteLayout 中的子级

等效 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 可以使用比例值来调整子级的位置和大小。 实现方式是,将子级添加到 AbsoluteLayoutChildren 集合,并将每个子级的 AbsoluteLayout.LayoutBounds 附加属性设置为 0-1 范围内的成比例位置和/或大小值。 通过在每个子级上设置 AbsoluteLayout.LayoutFlags 附加属性,使位置值和大小值成比例。

AbsoluteLayoutFlags 类型的 AbsoluteLayout.LayoutFlags 附加属性允许你设置一个标记,该标志指示子级的布局边界位置和大小值与 AbsoluteLayout 的大小成比例。 对子级进行布局时,AbsoluteLayout 会将位置和大小值相应地缩放以匹配任何设备的大小。

AbsoluteLayoutFlags 枚举定义以下成员:

  • None 表示这些值将被解释为绝对值。 这是附加属性 AbsoluteLayout.LayoutFlags 的默认值。
  • XProportional 表示 x 值将被解释为比例值,同时将所有其他值视为绝对值。
  • YProportional 表示 y 值将被解释为比例值,同时将所有其他值视为绝对值。
  • WidthProportional 表示 width 值将被解释为比例值,同时将所有其他值视为绝对值。
  • HeightProportional 表示 height 值将被解释为比例值,同时将所有其他值视为绝对值。
  • PositionProportional 表示 xy 值将被解释为比例值,而大小值则被解释为绝对值。
  • SizeProportional 表示 widthheight 值将被解释为比例值,而定位值则被解释为绝对值。
  • 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 附加属性中为每个子级指定的前两个值将使用比例值定义位置。 每个子级的大小由第三个和第四个绝对值定义,使用的是与设备无关的单位。

以下屏幕截图显示了生成的布局:

使用比例位置值放置在 AbsoluteLayout 中的子级

等效 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 范围之外的值来调整子级的位置和大小,使它们不在布局的边界内。