今天我们将使用Flutter创建以下布局。我们为什么要那样做?答案很简单:“练习变得完美”。
但是我们怎么能这样做呢?真的有可能像这样在彼此之上和之下扭曲方块吗?
我想到的第一种方法是使用九个方块,并相应地着色它们,如下所示:
但是可以使用更少的方块吗?也许是这样的:
上面的布局包含一个包装其他所有内容的列。在该列中,有两行。第一行有两个子项(红色和橙色),第二行有两列。第一列是绿色,第二列有两行,依此类推......
据我所知,橙色块不可能使用一个小部件,除非......我们使用stack,并将橙色块排列在其他块之上。
首先让我们创建上面的布局,之后,我们将看到如何使用橙色的stack。
在第一个中Row
,我们将创建两个“ Container”并将它们中的每一个包装在一个Expanded
小部件中,将flex因子设置为2表示红色Container
,1表示黄色表示。我也将他们的身高设定为100。
使用“ 扩展”窗口小部件可以使“ 行”或“ 列”的子项展开以填充主轴中的可用空间(例如,水平方向为行,或垂直方向为列)。如果扩展了多个子节点,则根据弹性因子将可用空间划分为多个子节点。
main_page.dart
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Squares'),
),
body: Column(
children: <Widget>[
Row(
children: <Widget>[
Expanded(
flex: 2,
child: Container(
height: 100,
color: Colors.red,
),
),
Expanded(
flex: 1,
child: Container(
height: 100,
color: Colors.orange,
),
),
],
),
],
),
);
}
现在让我们创建第二行。
对于第二行,我们将使用另外两个Expanded小部件,第一个使用flex因子1,第二个使用flex因子将是2。
在这一行中,我们将紫色和橙色块放在两个Expanded小部件中。但我们不会为它们指定弹性因子。因此,他们将平等占用可用空间:
main_page.dart
Row(
children: <Widget>[
Expanded(
flex: 1,
child: Container(
height: 200,
color: Colors.green,
),
),
Expanded(
flex: 2,
child: Column(
children: <Widget>[
Row(children: <Widget>[
Expanded(
child: Container(
height: 100,
color: Colors.purple,
),
),
Expanded(
child: Container(
height: 100,
color: Colors.orange,
),
),
],),
Container(
height: 100,
color: Colors.blue,
),
],
),
)
],
),
结果是:
要在每个块上显示白色数字,只需将Text小部件作为每个Container的子级,例如我们将拥有的红色Container:
main_page.dart
Expanded(
flex: 2,
child: Container(
height: 100,
color: Colors.red,
child: Center(
child: Text(
"1",
style: TextStyle(fontSize: 50, color: Colors.white),
),
),
),
),
请注意,我已将Text小部件包装在Center小部件中,以便文本显示在容器的中心:
我们差不多完成了,除了“2”号,它是居中的,但它没有居中!橙色块由两个不同的容器组成,数字“2”在下部容器中居中!
我们如何对齐此数字以使其居中?
我正在关注由Flutter的创作者创建的youtube上的一个频道,名为“ 本周的颤动小部件 ”。如果你还没有我完全建议你关注它!在上一集中,他们介绍了“Align”小部件,这对我们来说非常有用。
如下图所示,如果我们将对齐设置为(0,-1),对象将被放置在其容器内的顶部中心位置:
我用它来对齐下面橙色块内的文本。
我还尝试将对齐值设置为(0,-2.5)以将对象移动到其容器的上方(实际上是外部),并且它也起作用:
Expanded(
child: Container(
alignment: Alignment(0, -2.5),
height: 100,
color: Colors.orange,
child: Text(
"2",
style: TextStyle(fontSize: 50, color: Colors.white),
),
),
),
结果:
现在让我们使用“Stack”小部件从头开始创建所有内容。
Stack的孩子从下往上定位。因此第一个应该在其他人之下的孩子是紫色的,第5个:
stack_page.dart
body: Stack(
children: <Widget>[
Container(
color: Colors.purple,
height: 300,
child: Center(
child: Text(
"5",
style: TextStyle(fontSize: 50, color: Colors.white),
),
),
),
],
),
现在让我们添加堆栈的第二个子块,块号为1:
stack_page.dart
Container(
color: Colors.red,
height: 100,
width: MediaQuery.of(context).size.width * 2 / 3,
child: Center(
child: Text(
"1",
style: TextStyle(fontSize: 50, color: Colors.white),
),
),
),
请注意,我已使用MediaQuery
该类获取屏幕的宽度,然后将其乘以2/3。或者,我可以将容器包装在0.66(2/3)的FractionallySizedBox
类中,widthFactor
以实现红色块的相同宽度。另请注意,堆栈的子项默认位于堆栈的左上角。因此,我们不需要对齐红色块:
现在我们将橙色块放在stack上:
Align(
alignment: AlignmentDirectional.topEnd,
child: Container(
color: Colors.orange,
width: MediaQuery.of(context).size.width * 1 / 3,
height: 200,
child: Center(
child: Text(
"2",
style: TextStyle(fontSize: 50, color: Colors.white),
),
),
),
),
请注意,这一次,我将整个包装Container
在一个Align
小部件中,将小部件移动到堆栈的右上角。而这一次,橙色块的宽度是整个屏幕宽度的1/3:
添加和定位蓝色块有点棘手。因为如果你将它与“bottomRight”对齐,它最终会像这样:
这是因为我们没有为堆栈指定任何大小。因此它已经扩展到整个屏幕的大小。现在我们有两个选项来对齐蓝色块:
- 限制
Stack
高度。通过将其包装在SizedBox
窗口小部件中,并将height
属性设置为300。 - 手动对齐蓝色块。即使用
alignment: Alignment(1, -0.22)
而不是。alignment: AlignmentDirectional.*bottomEnd*
我选择实施第一个:
body: SizedBox(
height: 300,
child: Stack(
children: <Widget>[
结果:
将最后一个子项放在Stack上几乎与前一个相同,唯一的区别是它的宽度设置为屏幕宽度的1/3,它的位置是左下角,或者是BottmStart:
Align(
alignment: AlignmentDirectional.bottomStart,
child: Container(
color: Colors.green,
height: 200,
width: MediaQuery.of(context).size.width * 1 / 3,
child: Center(
child: Text("4",
style: TextStyle(fontSize: 50, color: Colors.white)),
),
),
),
结果:
最后的说明:
- 该
MediaQuery
课程对响应式设计非常有用。您可以使用它来查找屏幕的总大小,然后相应地设置小部件的大小。 - 该
Expanded
插件也是响应式设计非常方便,让你的部件由填充剩余的空间flex
你指定的因素。 - 如果要将窗口小部件放置在其父窗口中,请将窗口小部件包装在窗口
Align
小部件中,并alignment
相应地设置该属性。 - 如果没有为任何Stack的子项指定宽度和高度,默认情况下它们会将自身扩展到Stack的宽度和高度。
- 您还可以将Stack的每个子项包装在Positioned小部件中以对齐它们。
整个源代码可以在github上找到。
谢谢阅读!
翻译自:https://medium.com/@meysam.mahfouzi/flutter-layout-challenge-squares-3d0bc4c78793
网友评论