Flutter線性佈局Row和Column

白瑞德發表於2019-08-12

Flutter垂直和水平佈局

所謂線性佈局,即指沿水平或垂直方向排布子元件。Flutter中通過Row和Column來實現線性佈局,類似於Android中的LinearLayout控制元件。

主軸和縱軸(MainAxis & CrossAxis)

對於線性佈局,有主軸和縱軸之分,如果佈局是沿水平方向,那麼主軸就是指水平方向,而縱軸即垂直方向;如果佈局沿垂直方向,那麼主軸就是指垂直方向,而縱軸就是水平方向。線上性佈局中,MainAxisAlignmentCrossAxisAlignment,分別代表主軸對齊和縱軸對齊。線性佈局預設儘可能多的佔用主軸空間。預設是MainAxisSize.max,效果類似於Android佈局中的match_parent,而MainAxisSize.min表示儘可能少的佔用水平空間,當子元件沒有佔滿水平剩餘空間,則Row的實際寬度等於所有子元件佔用的的水平空間,效果類似於Android中的wrap_content; 需要注意的是:Row中主軸方向為水平方向,Column中的主軸方向為垂直方向,如圖:

Flutter線性佈局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,),
    ],
),
複製程式碼

效果如圖:

Flutter線性佈局Row和Column
其中Row的寬度和Column為填充父控制元件剩餘所有空間。

佈局方向

textDirection表示子元件在水平方向的佈局順序(是從左往右還是從右往左),預設為:TextDirection.ltr從左向右。在Column中使用此屬性沒有任何效果。對應效果分別為:

verticalDirection:表示縱軸的對齊方向,預設是VerticalDirection.down,表示從上到下。在Column中效果如下

Flutter線性佈局Row和Column
而在Row中則可以用改屬性設定字元件頭部對齊或者底部對齊,但一般採用crossAxisAlignment屬性進行設定。

對齊方式

MainAxisAlignment

mainAxisAlignment表示子元件在主軸方向上的對齊方式,如果mainAxisSize值為MainAxisSize.min,則此屬性無意義,因為子元件的寬度等於Row的寬度。 對齊方式有start、end、center、spaceBetween、spaceAround、spaceEvenly。對應的效果分別為:

start和end

表示沿主軸初始方向,預設為這種效果,子元件佈局方向沿著textDirection設定的佈局方向,和start表示逆主軸初始方向,子元件佈局方向逆著textDirection設定的佈局方向,效果如圖:

Flutter線性佈局Row和Column

center

center表示儘可能的將子元件靠近中間排列。效果如圖:

Flutter線性佈局Row和Column

spaceBetween、spaceAround和spaceEvenly

spaceBetween表示在子元件之間均勻的新增空白區域,讓每個元件和相鄰的元件都有相同的間距,但首尾元件與父元件沒有間隙。 spaceAround表示在子元件之間均勻的新增空白區域,讓每個元件和相鄰的元件都有相同的間距,但是首尾距離父邊界的距離為間距的一半。 spaceEvenly表示在子元件之間均勻的新增空白區域,讓每個元件和相鄰的元件都有相同的間距,但是首尾距離父邊界的距離和間距一樣。 效果如圖:

Flutter線性佈局Row和Column
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

startend是一對相反的對齊方式,在未設定verticalDirection屬性時(預設VerticalDirection.down),start表示頂部對齊,end表示底部對齊。而當verticalDirectionVerticalDirection.up時,start表示底部對齊,end表示頂部對齊。效果如下圖:

Flutter線性佈局Row和Column

stretch和baseline

stretch表示子元件填滿縱軸方向。 baseline表示沿橫軸放置子級,以便其基線匹配,如果主軸是垂直的,那麼它的效果和start一樣。

特殊情況

如果Row裡面巢狀Row,或者Column裡面再巢狀Column,那麼只有對最外面的RowColumn會佔用盡可能大的空間,裡面RowColumn所佔用的空間為實際大小。

預設屬性

通過閱讀RowColumn的原始碼,可以瞭解到它們的預設屬性:

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相關知識連結:

React Flexbox佈局

CSS3 Flexbox 口訣

相關文章