Chinaunix首页 | 论坛 | 博客
  • 博客访问: 6658257
  • 博文数量: 915
  • 博客积分: 17977
  • 博客等级: 上将
  • 技术积分: 8846
  • 用 户 组: 普通用户
  • 注册时间: 2005-08-26 09:59
个人简介

一个好老好老的老程序员了。

文章分类

全部博文(915)

文章存档

2022年(9)

2021年(13)

2020年(10)

2019年(40)

2018年(88)

2017年(130)

2015年(5)

2014年(12)

2013年(41)

2012年(36)

2011年(272)

2010年(1)

2009年(53)

2008年(65)

2007年(47)

2006年(81)

2005年(12)

分类: Android平台

2018-08-28 20:25:42

在Xamarin.Forms中,布局的概念包含了可以在屏幕上组合各种视图的所有方式。 这是类层次结构,显示从Layout派生的所有类:

点击(此处)折叠或打开

  1. System.Object
  2.     BindableObject
  3.         Element
  4.             VisualElement
  5.                 View
  6.                     Layout
  7.                         ContentView
  8.                             Frame
  9.                         ScrollView
  10.                         Layout<T>
  11.                             AbsoluteLayout
  12.                             Grid
  13.                             RelativeLayout
  14.                             StackLayout

你已经看过ContentView,Frame和ScrollView(所有这些都有一个你可以设置为一个子节点的Content属性),你已经看到了StackLayout,它继承了Layout 中的Children属性并显示了它的子节点垂直或水平堆叠。 Grid和RelativeLayout实现了一些复杂的布局模型,并将在以后的章节中进行探讨。 AbsoluteLayout是本章的主题。
起初,AbsoluteLayout类似乎实现了一个相当原始的布局模型 - 当程序员需要单独调整大小并定位屏幕上的每个元素时,这个模型可以追溯到不太好的图形用户界面。然而,你会发现AbsoluteLayout还采用了比例定位和尺寸调整功能,有助于将这种古老的布局模型带入现代。
使用AbsoluteLayout,到目前为止您学习的许多关于布局的规则不再适用:当View是ContentPage或StackLayout的子项时,如此重要的HorizontalOptions和VerticalOptions属性在View是子项时绝对没有效果一个AbsoluteLayout。程序必须为AbsoluteLayout的每个子项分配与设备无关的坐标中的特定位置。还可以为孩子分配特定大小或允许孩子自己调整大小。
您可以在代码或XAML中使用AbsoluteLayout。 无论哪种方式,您都会遇到一个您尚未看到的功能,这是BindableObject和BindableProperty提供的支持的另一部分。 此新功能是附加的可绑定属性。 这是一种特殊类型的可绑定属性,由一个类(在本例中为AbsoluteLayout)定义,但在其他对象(AbsoluteLayout的子节点)上设置。

代码中的AbsoluteLayout

您可以像使用StackLayout一样将子视图添加到AbsoluteLayout的Children集合中:

点击(此处)折叠或打开

  1. absoluteLayout.Children.Add(child);
但是,您还有其他选择。 AbsoluteLayout类将其Children属性重新定义为AbsoluteLayout.IAbsoluteList 类型,其中包括两个额外的Add方法,允许您指定子项相对于AbsoluteLayout左上角的位置。 您可以选择指定孩子的大小。


要指定位置和大小,请使用Rectangle值。 Rectangle是一个结构,您可以使用接受Point和Size值的构造函数创建Rectangle值:

点击(此处)折叠或打开

  1. Point point = new Point(x, y);
  2. Size size = new Size(width, height);
  3. Rectangle rect = new Rectangle(point, size);
或者,您可以将x,y,width和height参数直接传递给Rectangle构造函数:

点击(此处)折叠或打开

  1. Rectangle rect = new Rectangle(x, y, width, height);
然后,您可以使用另一种Add方法将视图添加到AbsoluteLayout的Children集合中:

点击(此处)折叠或打开

  1. absoluteLayout.Children.Add(child, rect);
x和y值指示子视图的左上角相对于设备无关坐标中AbsoluteLayout父项的左上角的位置。 如果您希望孩子自己调整大小,则只能使用没有Size值的Point值:

点击(此处)折叠或打开

  1. absoluteLayout.Children.Add(child, point);
这是一个名为AbsoluteDemo的程序中的一个小演示:

点击(此处)折叠或打开

  1. public class AbsoluteDemoPage : ContentPage
  2. {
  3.     public AbsoluteDemoPage()
  4.     {
  5.         AbsoluteLayout absoluteLayout = new AbsoluteLayout
  6.         {
  7.             Padding = new Thickness(50)
  8.         };
  9.         absoluteLayout.Children.Add(
  10.             new BoxView
  11.             {
  12.                 Color = Color.Accent
  13.             },
  14.             new Rectangle(0, 10, 200, 5));
  15.         absoluteLayout.Children.Add(
  16.             new BoxView
  17.             {
  18.                 Color = Color.Accent
  19.             },
  20.             new Rectangle(0, 20, 200, 5));
  21.         absoluteLayout.Children.Add(
  22.             new BoxView
  23.             {
  24.                 Color = Color.Accent
  25.             },
  26.             new Rectangle(10, 0, 5, 65));
  27.         absoluteLayout.Children.Add(
  28.             new BoxView
  29.             {
  30.                 Color = Color.Accent
  31.             },
  32.             new Rectangle(20, 0, 5, 65));
  33.         absoluteLayout.Children.Add(
  34.             new Label
  35.             {
  36.                 Text = "Stylish Header",
  37.                 FontSize = 24
  38.             },
  39.             new Point(30, 25));
  40.         absoluteLayout.Children.Add(
  41.             new Label
  42.             {
  43.                 FormattedText = new FormattedString
  44.                 {
  45.                     Spans =
  46.                     {
  47.                         new Span
  48.                         {
  49.                             Text = "Although the "
  50.                         },
  51.                         new Span
  52.                         {
  53.                             Text = "AbsoluteLayout",
  54.                             FontAttributes = FontAttributes.Italic
  55.                         },
  56.                         new Span
  57.                         {
  58.                             Text = " is usually employed for purposes other " +
  59.                                    "than the display of text using "
  60.                         },
  61.                         new Span
  62.                         {
  63.                             Text = "Label",
  64.                             FontAttributes = FontAttributes.Italic
  65.                         },
  66.                         new Span
  67.                         {
  68.                             Text = ", obviously it can be used in that way. " +
  69.                                    "The text continues to wrap nicely " +
  70.                                    "within the bounds of the container " +
  71.                                    "and any padding that might be applied."
  72.                         }
  73.                     }
  74.                 }
  75.             },
  76.             new Point(0, 80));
  77.         this.Content = absoluteLayout;
  78.     }
  79. }
四个BoxView元素在顶部形成一个重叠的十字形图案以引出标题,然后是一段文字。 程序定位和调整所有BoxView元素,而它只是定位两个Label视图,因为它们自己调整大小:

需要进行一些试验和错误才能使四个BoxView元素的大小和标题文本的大小大致相同。但请注意BoxView元素重叠:AbsoluteLayout允许您以非常自由的方式重叠视图,这对于StackLayout来说根本不可能(或者不使用变换,这将在后面的章节中介绍)。
AbsoluteLayout的一大缺点是你需要自己设定定位坐标或在运行时计算它们。任何未明确调整大小的内容(例如两个Label视图)都会在页面布局时计算自身的大小。但是那个尺寸直到那时才可用。如果您想在第二个Label之后添加另一个段落,您会使用什么坐标?
实际上,您可以通过在AbsoluteLayout中放置StackLayout(或ScrollView内的StackLayout)然后将Label视图放入其中来定位多段文本。布局可以嵌套。
您可以推测,使用AbsoluteLayout比使用StackLayout更困难。通常,让Xamarin.Forms和其他布局类为您处理大部分布局复杂性要容易得多。但对于一些特殊用途,AbsoluteLayout是理想的选择。
与所有可视元素一样,AbsoluteLayout默认将其HorizontalOptions和VerticalOptions属性设置为Fill,这意味着AbsoluteLayout填充其容器。使用HorizontalOptions和VerticalOptions的其他设置,AbsoluteLayout将自身的大小调整为其内容的大小,但也有一些例外:尝试在AbsoluteDemo中给出AbsoluteLayout
编程BackgroundColor,以便您可以准确地看到它在屏幕上占据的空间。它通常填充整个页面,但是如果设置HorizontalOptions和VerticalOptions属性
对于中心的AbsoluteLayout,您将看到AbsoluteLayout为其自身计算的大小包括内容和填充,但只包含文本段落的一行。
确定AbsoluteLayout中视觉元素的大小可能很棘手。下面的ChessboardFixed程序演示了一种简单的方法。程序名称后缀为Fixed,因为棋盘中所有方块的位置和大小都是在构造函数中设置的。构造函数无法预测屏幕的大小,因此它可以任意设置每个方块的大小为35个单位,如类顶部的squareSize常量所示。此值应足够小,以使棋盘适合Xamarin.Forms支持的任何设备的屏幕。
请注意,AbsoluteLayout是居中的,因此它的大小可以容纳其所有子节点。电路板本身有浅黄色,浅黄色,然后在每个其他方形位置显示32个深绿色BoxView元素:

点击(此处)折叠或打开

  1. public class ChessboardFixedPage : ContentPage
  2. {
  3.     public ChessboardFixedPage()
  4.     {
  5.         const double squareSize = 35;
  6.         AbsoluteLayout absoluteLayout = new AbsoluteLayout
  7.         {
  8.             BackgroundColor = Color.FromRgb(240, 220, 130),
  9.             HorizontalOptions = LayoutOptions.Center,
  10.             VerticalOptions = LayoutOptions.Center
  11.         };
  12.         for (int row = 0; row < 8; row++)
  13.         {
  14.             for (int col = 0; col < 8; col++)
  15.             {
  16.                 // Skip every other square.
  17.                 if (((row ^ col) & 1) == 0)
  18.                     continue;
  19.                 BoxView boxView = new BoxView
  20.                 {
  21.                     Color = Color.FromRgb(0, 64, 0)
  22.                 };
  23.                 Rectangle rect = new Rectangle(col * squareSize,
  24.                                                row * squareSize,
  25.                                                squareSize, squareSize);
  26.                 absoluteLayout.Children.Add(boxView, rect);
  27.             }
  28.         }
  29.         this.Content = absoluteLayout;
  30.     }
  31. }
对row和col变量的异或计算仅在row或col变量为奇数但两者都不是奇数时才会创建BoxView。 这是结果:

阅读(2113) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~