欢迎来到 Flutter 布局 codelab!你将在这里学到如何构建 Flutter UI,更棒的是这一切都不需要安装 Flutter 或者 Dart!
Flutter 与其他框架有着明显的差异,原因在于它使用代码来构建 UI,而不是 XML 或其他东西。其中,Widget 是构建 Flutter UI 的基本单元。当你逐渐深入这个 codelab,你将会发现在 Flutter 中几乎所有的东西都是 Widget。Widget 是一个不会改变的对象,它是 UI 中一个特定部分的描述。你还会学到 Flutter 的 Widget 非常容易组合,这意味着你能够通过组合已有的 Widgets 来创造更多复杂的 Widgets。到这篇文章的最后,你会运用这里所学的知识构建一个显示名片的 Flutter UI。
本 codelab 的预期完成时间约为 45 - 60 分钟
1. Row 和 Column 类
Row
和 Column
是两个用来容纳和布局 Widgets 的类。在它们内部的 Widgets 我们称为 children, Row
和 Column
就作为它们的父级。 Row
将会让 Widgets 水平排列,而 Column 则会让其竖直排列。
样例:创建一个 Column
2. 轴大小和对齐方式
至此,BlueBox
widget 已经在一起被压扁了(在界面的左边或者上面)。你可以通过轴大小和对齐属性来改变 BlueBox
Widget 的间距。2.1 mainAxisSize 属性
Row
和 Column
分别占据了不同的主轴。Row
的主轴是水平的。 mainAxisSize
决定了 Row
和 Column
能够在主轴上占据多大空间。mainAxisSize
有两个可选属性:MainAxisSize.max
Row
和 Column
占据它们主轴上所有空间。如果子 Widget 的总宽度小于主轴上的空间,它们就会充满剩余的空间。MainAxisSize.min
Row
和 Column
仅占据它的 children 在主轴上所需的空间,它的 children 在主轴之间将没有额外空间。当 mainAxisSize
被设为 MainAxisSize.max
, Row
和 Column
将会使用额外空间来对齐它的 children。 mainAxisAlignment
属性决定了 Row
和 Column
将会在额外空间中如何对齐它的 children。 mainAxisAlignment
有以下六个可选属性:MainAxisAlignment.start
将其 children 从主轴起点处开始对齐。(Row
的起点在左边,Column
的起点在顶部)MainAxisAlignment.end
将其 children 从主轴终点处开始对齐。(Row
的终点在右边,Column
的终点在底部)MainAxisAlignment.center
将其 children 置于主轴中心。MainAxisAlignment.spaceBetween
在 children 之间平均分配额外空间。MainAxisAlignment.spaceEvenly
在 children 之间,以及第一个 children 之前和最后一个 children 之后,平均分配额外空间。MainAxisAlignment.spaceAround
与 MainAxisAlignment.spaceEvenly
相似,但在第一个 child 之前以及最后一个孩子之后减少了一半的空间,让其 children 之间宽度缩减一半。2.3 crossAxisAlignment 属性
crossAxisAlignment
属性决定了 Row
和 Column
能够如何在其横轴上定位 children。 Row
的横轴是竖直的,而 Column
则是水平的。绝大多数 crossAxisAlignment
属性仅在 Row
中生效。 crossAxisAlignment
属性有五个可选属性:CrossAxisAlignment.start
将其 children 横轴顶部对齐。(只在 Row
中生效)CrossAxisAlignment.end
将其 children 横轴底部对齐。(只在 Row
中生效)CrossAxisAlignment.center
将其 children 横轴中心对齐。(只在 Row
中生效)CrossAxisAlignment.stretch
沿横轴延伸 children。(在 Row
中是从顶至底,Column
则是从左至右)CrossAxisAlignment.baseline
根据 children 的基线对子节点。(仅限Text
类,并要求 textBaseline
属性设置为 TextBaseline.alphabetic
。3. Flexible widget
正如你所看到,mainAxisAlignment
和 crossAxisAlignment
属性决定了 Row
和 Column
在各个轴上如何布局 widget。 Row
和 Column
首先布置固定大小的 widget。固定大小的小部件被认为是 不灵活的 因为它们布局后无法自我调整大小。Flexible
widget 包裹一个 widget 让这个 widget 变得可以调整大小。当 Flexible
widget 包裹 widget 时,这个 Widget 就成为 Flexible
widget 的子节点,并被视为 flexible 的。在布置固定大小的 widget 后, Flex 的 widget 根据其 flex
和 fit
属性调整大小:flex
将自身的 flex
因子与其他的比较,以决定自身占剩余空间的比例。fit
决定 Flexible
的 Widget 是否能够填充所有剩余空间。样例:改变 fit 属性
4. Expanded widget
Expanded
widget 能够包裹一个 Widget 并强制其填满剩余空间,与 Flexible
非常相似。5. SizedBox widget
SizedBox
widget 的两种用途之一就是创建精确的尺寸。当 SizedBox
包裹了一个 Widget 时,它会使用 height
和 width
调整其大小。如果它没有包裹 Widget,它可以使用height
和width
属性创造空的空间。6. Spacer widget
与 SizedBox
相似,Spacer
widget 也能在 Widgets 之间创建空间。7. Text widget
Text
widget 不仅能够显示文字,并能够配置不同的字体,大小和颜色。Icon
Widget 能够显示图形符号,这代表了 UI 的一个方面。Flutter 将会为 Material 和 Cupertino 的应用提前加载 icon packages。
Image
widget 显示了一张图片。你还能够直接引用图片 URL,或是你的应用 package 中的图片。但是由于 DartPad 无法引用包图片,所以下面的样例将会使用网络上的图片。你就要完成这个 codelab 了!如果你想要检验你刚学的知识,为何不讲这些结合起来,构建一个显示名片的 Flutter UI 呢!你将会把 Flutter 的布局分解成几个部分,这就是如何在实际开发中构建 Flutter UI 方式!在第一部分, 你将会实现包含姓名和标题的 Column
。然后你将会在 Column
包裹一个含有 icon 的 Row
,它将会被放在姓名和标题的左边。在第二部分中,你将会在 Row
外包裹一个 Column
,所以你的代码中就包含了一个 Column(Row(Column))。然后你将调整最外面的Column
的布局,所以它看起来不错。最后,您将添加联系信息到最外面的Column
的 children 中,所以它将显示在名称,标题和图标下方。在第三部分,你将会完成添加了更多图标的名片,它们会被放在联系信息的下方。恭喜你,已经完成了这个 codelab!如果你想要了解关于 Flutter 的更多信息,这里有些值得探索的资源要推荐给你:- 访问 Flutter’s YouTube channel,你将能够观看大量专注于独立的 widget 以及开发者如何构建应用的视频。