Flutter垂直和水平佈局
所謂線性佈局,即指沿水平或垂直方向排布子元件。Flutter中通過Row和Column來實現線性佈局,類似於Android中的LinearLayout控制元件。
主軸和縱軸(MainAxis & CrossAxis)
對於線性佈局,有主軸和縱軸之分,如果佈局是沿水平方向,那麼主軸就是指水平方向,而縱軸即垂直方向;如果佈局沿垂直方向,那麼主軸就是指垂直方向,而縱軸就是水平方向。線上性佈局中,MainAxisAlignment
和CrossAxisAlignment
,分別代表主軸對齊和縱軸對齊。線性佈局預設儘可能多的佔用主軸空間。預設是MainAxisSize.max
,效果類似於Android佈局中的match_parent
,而MainAxisSize.min
表示儘可能少的佔用水平空間,當子元件沒有佔滿水平剩餘空間,則Row的實際寬度等於所有子元件佔用的的水平空間,效果類似於Android中的wrap_content
;
需要注意的是:Row中主軸方向為水平方向,Column中的主軸方向為垂直方向,如圖:
Row和Column的基本使用和效果如下:
new Row(
children: <Widget>[
new View(color: Colors.red),
new View(color: Colors.yellow),
new View(color: Colors.blue,),
],
),
new Column(
children: <Widget>[
new View(color: Colors.red),
new View(color: Colors.yellow),
new View(color: Colors.blue,),
],
),
複製程式碼
效果如圖:
其中Row的寬度和Column為填充父控制元件剩餘所有空間。佈局方向
textDirection
表示子元件在水平方向的佈局順序(是從左往右還是從右往左),預設為:TextDirection.ltr
從左向右。在Column中使用此屬性沒有任何效果。對應效果分別為:
verticalDirection:表示縱軸的對齊方向,預設是VerticalDirection.down,表示從上到下。在Column
中效果如下
Row
中則可以用改屬性設定字元件頭部對齊或者底部對齊,但一般採用crossAxisAlignment
屬性進行設定。
對齊方式
MainAxisAlignment
mainAxisAlignment
表示子元件在主軸方向上的對齊方式,如果mainAxisSize
值為MainAxisSize.min
,則此屬性無意義,因為子元件的寬度等於Row的寬度。
對齊方式有start、end、center、spaceBetween、spaceAround、spaceEvenly
。對應的效果分別為:
start和end
表示沿主軸初始方向,預設為這種效果,子元件佈局方向沿著textDirection
設定的佈局方向,和start
表示逆主軸初始方向,子元件佈局方向逆著textDirection
設定的佈局方向,效果如圖:
center
center
表示儘可能的將子元件靠近中間排列。效果如圖:
spaceBetween、spaceAround和spaceEvenly
spaceBetween
表示在子元件之間均勻的新增空白區域,讓每個元件和相鄰的元件都有相同的間距,但首尾元件與父元件沒有間隙。
spaceAround
表示在子元件之間均勻的新增空白區域,讓每個元件和相鄰的元件都有相同的間距,但是首尾距離父邊界的距離為間距的一半。
spaceEvenly
表示在子元件之間均勻的新增空白區域,讓每個元件和相鄰的元件都有相同的間距,但是首尾距離父邊界的距離和間距一樣。
效果如圖:
MainAxisAlignment.center
為例,其使用方法為:
new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new View(color: Colors.red),
new View(color: Colors.yellow),
new View(color: Colors.blue,),
],
),
複製程式碼
CrossAxisAlignment
CrossAxisAlignment
表示子元件在縱軸方向上的對齊方式。對齊方式有:start、end、center、stretch、baseline
。
start和end
start
和end
是一對相反的對齊方式,在未設定verticalDirection
屬性時(預設VerticalDirection.down
),start
表示頂部對齊,end
表示底部對齊。而當verticalDirection
為VerticalDirection.up
時,start
表示底部對齊,end
表示頂部對齊。效果如下圖:
stretch和baseline
stretch
表示子元件填滿縱軸方向。
baseline
表示沿橫軸放置子級,以便其基線匹配,如果主軸是垂直的,那麼它的效果和start
一樣。
特殊情況
如果Row
裡面巢狀Row
,或者Column
裡面再巢狀Column
,那麼只有對最外面的Row
或Column
會佔用盡可能大的空間,裡面Row
或Column
所佔用的空間為實際大小。
預設屬性
通過閱讀Row
和Column
的原始碼,可以瞭解到它們的預設屬性:
Row({
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>[],
}) : super(
children: children,
key: key,
direction: Axis.horizontal,
mainAxisAlignment: mainAxisAlignment,
mainAxisSize: mainAxisSize,
crossAxisAlignment: crossAxisAlignment,
textDirection: textDirection,
verticalDirection: verticalDirection,
textBaseline: textBaseline,
);
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>[],
}) : super(
children: children,
key: key,
direction: Axis.vertical,
mainAxisAlignment: mainAxisAlignment,
mainAxisSize: mainAxisSize,
crossAxisAlignment: crossAxisAlignment,
textDirection: textDirection,
verticalDirection: verticalDirection,
textBaseline: textBaseline,
);
複製程式碼
概括如下:
屬性 | 預設值 |
---|---|
mainAxisAlignment | start |
mainAxisSize | max |
crossAxisAlignment | center |
verticalDirection | down |
總結
瞭解了Flutter線性佈局之後,不難發現,其設計思想和使用方式都和React及其類似,建議將二者放在一起對比學習。 附上React相關知識連結: