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轉(zhuǎn)過來的同學了若指掌。
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代碼為例,展現(xiàn)的效果圖為
<img src="https://upload-images.jianshu.io/upload_images/4025850-8973ee9114cc26aa.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="screenshot-1569483899301.jpg" style="zoom: 25%;" />
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的數(shù)量進行等分,并且child在分配的空間居中顯示,代碼與上面相同,僅改變MainAxisAlignment.spaceBetween為MainAxisAlignment.spaceAround
<img src="https://upload-images.jianshu.io/upload_images/4025850-9b26808e12a868cd.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="screenshot-1569484302267.jpg" style="zoom:25%;" />
可以明顯看出,第一個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放在兩個空間的中間:
<img src="https://upload-images.jianshu.io/upload_images/4025850-03891bd6d0b765f7.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="screenshot-1569484756442.jpg" style="zoom:25%;" />
child的上下空間一樣,并且與兩端的child相距邊緣的空間也一致,可以數(shù)到,被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),
),
],
)
<img src="https://upload-images.jianshu.io/upload_images/4025850-8afe990cf13bcdfc.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="screenshot-1569488114614.jpg" style="zoom:25%;" />
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在副軸的方向取最大
<img src="https://upload-images.jianshu.io/upload_images/4025850-b02fb1d8eaf249da.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="screenshot-1569488186976.jpg" style="zoom:25%;" />
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(表意)
<img src="https://upload-images.jianshu.io/upload_images/4025850-77747d4517063e48.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="screenshot-1569548619278.jpg" style="zoom:25%;" />
不過,修改兩個屬性,是真的沒有發(fā)現(xiàn)文字對齊有什么不一樣,抱歉。
d) textDirection
A direction in which text flows.
文字流動的方向
可以理解為橫向的排布方向,這里有兩個屬性可選:
- ltr(left to right)
- rtl(right to left)
正常情況下,系統(tǒng)默認為ltr,兩者對比如下:
ltr
<img src="https://upload-images.jianshu.io/upload_images/4025850-f65b631bcf350028.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png" style="zoom: 67%;" />
rtl
<img src="https://upload-images.jianshu.io/upload_images/4025850-cd62f7c88102194f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="image.png" style="zoom:67%;" />
e) verticalDirection
A direction in which boxes flow vertically.
垂直流動的方向
就是縱向的排布方向,也是有兩個屬性可選:
- up
- down
系統(tǒng)默認為down,即向下流動(從上往下排列),因為和textDirection屬性太相似,這里不單獨截圖做對比。
f) children
最后的關鍵,孩子們。
children的屬性是List<Widget>,使用方式前面代碼里面已經(jīng)展示,需要注意的一點就是children總大小不要超過了Column&Row的長寬,不然會報錯,這點和Android還是有點差別的。
3. 總結(jié)
從Android轉(zhuǎn)到Flutter的同學可以放心的食用Column&Row,腦中就想著在使用LinearLayout就可以了。
- Column為縱向布局,Row為橫向布局
- 主軸方向和副軸方向上的對齊方式都有多重選擇
- 主軸方向默認取最大,可以設置為取最小
- 涉及到文字排布時,可以使用baseline&textBaseline來使排版更好看
- 主軸方向的排列順序也可以設置
- Column對應verticalDirection
- Row對應textDirection
- 布置孩子時,需要注意總長寬不可以大于Row&Column的長寬,不然會報異常