1. 简述
Row
和Column
分别是横向布局和纵向布局,对标Android中的LinearLayout
<!-- Row -->
<LinearLayout
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="wrap_content">
</LinearLayout>
<!-- Column -->
<LinearLayout
android:layout_width="wrap_content"
android:orientation="vertical"
android:layout_height="match_parent">
</LinearLayout>
Row和Column默认会在主轴方向取最大,即上面XML代码中展示的,Row相对应LinearLayout的layout_width
为match_parent
,Column相对应LinearLayout的layout_height
为match_parent
。
2. 使用
Row和Column的使用相似,以Column为例看一下构造方法
Column({
Key key,
MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
MainAxisSize mainAxisSize = MainAxisSize.max,
CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,
TextDirection textDirection,
VerticalDirection verticalDirection = VerticalDirection.down,
TextBaseline textBaseline,
List<Widget> children = const <Widget>[],
})
a) mainAxisAlignment
主轴的对齐方式,默认为MainAxisAlignment.start
,即在布局的开始进行children的排列,下面列下所有的主轴对中mode:
- start
- end
- center
- spaceBetween
- spaceAround
- spaceEvenly
start、end、center这里不需要多说,Android转过来的同学了若指掌。
spaceBetween
Place the free space evenly between the children. 将空闲空间均匀地放在孩子之间
将空间均匀的分布在children之间,并且布局两头的child会抵住布局的两端,不留空间。
Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Icon(Icons.ac_unit),
Icon(Icons.ac_unit),
Icon(Icons.ac_unit),
],
)
以上面的Column代码为例,展现的效果图为
spaceAround
Place the free space evenly between the children as well as half of that space before and after the first and last child.
在第一个和最后一个孩子之前和之后的子对象之间以及剩余空间的一半之间均匀地分配可用空间
通俗来讲,就是将空间按children的数量进行等分,并且child在分配的空间居中显示,代码与上面相同,仅改变MainAxisAlignment.spaceBetween
为MainAxisAlignment.spaceAround
可以明显看出,第一个child的上面空间,是其下面空间的一半>。
spaceEvenly
Place the free space evenly between the children as well as before and after the first and last child.
在第一个和最后一个孩子之前和之后的孩子之间均匀地分配可用空间。
均匀的分配空间,这里可以看做将空间减去children所占空间后,按children的count+1等分,并且将child放在两个空间的中间:
child的上下空间一样,并且与两端的child相距边缘的空间也一致,可以数到,被child分割的大小相同的空间,共有children.count+1份。
b) mainAxisSize
主轴的尺寸,即我们前面说的,Column和Row默认下主轴方向取最大。
这里可选择的属性只有两种:
- max
- min
相对应的,即为Android的match_parent
和wrap_content
c) crossAxisAlignment
副轴对齐方式,Column的主轴是纵轴,相对应的副轴就是横轴。
依然列出所有mode:
- start
- end
- center
- stretch
- baseline
因为baseline的特殊性,这次用Row作为示例。依然对前三个予以蔑视。
Row(
children: <Widget>[
Container(
color: Colors.greenAccent,
child: Icon(Icons.accessibility),
),
Container(
color: Colors.amberAccent,
child: Icon(Icons.accessibility),
),
Container(
color: Colors.blue,
child: Icon(Icons.accessibility),
),
],
)
stretch
Require the children to fill the cross axis.
This causes the constraints passed to the children to be tight in the cross axis.
要求孩子填充交叉轴。
这导致传递给子代的约束在交叉轴上很紧。
就是让child在副轴的方向取最大
baseline & TextBaseline
Place the children along the cross axis such that their baselines match. If the main axis is vertical, then this value is treated like [start] (since baselines are always horizontal). 沿十字轴放置孩子,使其基线匹配。 如果主轴是垂直的,则将此值视为[start](因为基线始终是水平的)。
这个属性对应的是文字基线对齐,要配合TextBaseline
属性来使用。
TextBaseline包含两个属性:alphabetic(字母)、ideographic(表意)
不过,修改两个属性,是真的没有发现文字对齐有什么不一样,抱歉。
d) textDirection
A direction in which text flows.
文字流动的方向
可以理解为横向的排布方向,这里有两个属性可选:
- ltr(left to right)
- rtl(right to left)
正常情况下,系统默认为ltr,两者对比如下:
ltr
rtl
e) verticalDirection
A direction in which boxes flow vertically.
垂直流动的方向
就是纵向的排布方向,也是有两个属性可选:
- up
- down
系统默认为down
,即向下流动(从上往下排列),因为和textDirection属性太相似,这里不单独截图做对比。
f) children
最后的关键,孩子们。
children的属性是List<Widget>
,使用方式前面代码里面已经展示,需要注意的一点就是children总大小不要超过了Column&Row的长宽,不然会报错,这点和Android还是有点差别的。
3. 总结
从Android转到Flutter的同学可以放心的食用Column&Row,脑中就想着在使用LinearLayout就可以了。
- Column为纵向布局,Row为横向布局
- 主轴方向和副轴方向上的对齐方式都有多重选择
- 主轴方向默认取最大,可以设置为取最小
- 涉及到文字排布时,可以使用baseline&textBaseline来使排版更好看
- 主轴方向的排列顺序也可以设置
- Column对应verticalDirection
- Row对应textDirection
- 布置孩子时,需要注意总长宽不可以大于Row&Column的长宽,不然会报异常