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的長寬,不然會報異常