所谓线性布局,就是指沿水平或垂直方向排布子组件。

Flutter当中的Row和Column两个控件叠加的效果相当于Android里面的LinearLayout。

1、Row

因为Row和Column都是继承于同一个类,所以他们的属性都一样,这些属性里面既包含了针对Row的属性,也包含了针对Column的属性。

常用属性值含义
textDirection(仅Row有效)子布局方向
mainAxisAlignment(仅Row有效)子布局整体对齐方式(靠坐、靠右、两端对齐等)
mainAxisSize(仅Row有效)父布局水平撑满还是自适应,max是撑满,min是自定义
verticalDirection(仅Column有效)表示Row纵轴(垂直)的对齐方向,默认是VerticalDirection.down,表示从上到下
crossAxisAlignment(仅Column有效)表示子组件在纵轴方向的对齐方式
children子布局数组
  • textDirection:

表示水平方向子组件的布局顺序(是从左往右还是从右往左),默认为系统当前Locale环境的文本方向(如中文、英语都是从左往右,而阿拉伯语是从右往左)。

  • mainAxisSize:

表示Row在主轴(水平)方向占用的空间,默认是MainAxisSize.max,表示尽可能多的占用水平方向的空间,此时无论子widgets实际占用多少水平空间,Row的宽度始终等于水平方向的最大宽度;而MainAxisSize.min表示尽可能少的占用水平空间,当子组件没有占满水平剩余空间,则Row的实际宽度等于所有子组件占用的的水平空间;

  • mainAxisAlignment:

表示子组件在Row所占用的水平空间内对齐方式,如果mainAxisSize值为MainAxisSize.min,则此属性无意义,因为子组件的宽度等于Row的宽度。只有当mainAxisSize的值为MainAxisSize.max时,此属性才有意义,MainAxisAlignment.start表示沿textDirection的初始方向对齐,如textDirection取值为TextDirection.ltr时,则MainAxisAlignment.start表示左对齐,textDirection取值为TextDirection.rtl时表示从右对齐。而MainAxisAlignment.endMainAxisAlignment.start正好相反;MainAxisAlignment.center表示居中对齐。读者可以这么理解:textDirectionmainAxisAlignment的参考系。

  • verticalDirection:

表示Row纵轴(垂直)的对齐方向,默认是VerticalDirection.down,表示从上到下。

  • crossAxisAlignment:

表示子组件在纵轴方向的对齐方式,Row的高度等于子组件中最高的子元素高度,它的取值和MainAxisAlignment一样(包含startend、 center三个值),不同的是crossAxisAlignment的参考系是verticalDirection,即verticalDirection值为VerticalDirection.downcrossAxisAlignment.start指顶部对齐,verticalDirection值为VerticalDirection.up时,crossAxisAlignment.start指底部对齐;而crossAxisAlignment.endcrossAxisAlignment.start正好相反;

  • children:子组件数组。

1.1、 示例

         new Row(
            //子布局方向
            textDirection: TextDirection.rtl,
            //子布局整体对齐方式(靠坐、靠右、两端对齐等)
            mainAxisAlignment: MainAxisAlignment.center,
            //父布局水平撑满还是自适应,max是撑满,min是自定义。
            mainAxisSize: MainAxisSize.max,
            children: <Widget>[
              new Text("one", style: new TextStyle(color: Colors.red)),
              new Text("two", style: new TextStyle(color: Colors.green)),
              new Text("three", style: new TextStyle(color: Colors.blue)),
            ],
          ),

1.2、效果图:

Row示例效果

解释:

  • 因为设置了textDirection: TextDirection.rtl,,所以子布局排列从又到左。
  • 因为设置了mainAxisAlignment: MainAxisAlignment.center`,所以子布局整体居中。

2、Column

Column可以在垂直方向排列其子组件。参数和Row一样,不同的是布局方向为垂直,主轴纵轴正好相反,可类比Row来理解。

2.1、示例:

          new Column(
            //父布局水平撑满还是自适应,max是撑满,min是自定义。
            mainAxisSize: MainAxisSize.max,
            //子布局左右对齐(仅对Column有效)
            crossAxisAlignment: CrossAxisAlignment.end,
            //垂直方向上的对齐方式(仅对Column有效)
            verticalDirection: VerticalDirection.up,
            children: <Widget>[
              new Text("four", style: new TextStyle(color: Colors.red)),
              new Text("five", style: new TextStyle(color: Colors.green)),
              new Text("six", style: new TextStyle(color: Colors.blue)),
            ],
          )

2.2、效果图:

Column示例图

解释:

  • 因为设置了crossAxisAlignment: CrossAxisAlignment.end,所以三个文案靠右对齐。
  • 因为设置了verticalDirection: VerticalDirection.up,所以子布局排列是从下到上。

实际上,RowColumn都只会在主轴方向占用尽可能大的空间,而纵轴的长度则取决于他们最大子元素的长度

3、特殊情况

3.1、空间说明

如果Row里面嵌套Row,或者Column里面再嵌套Column,那么只有对最外面的RowColumn会占用尽可能大的空间,里面RowColumn所占用的空间为实际大小,下面以Column为例说明:

          Container(
            color: Colors.green,
            constraints: BoxConstraints(minWidth: double.infinity),
            child: Padding(
              padding: const EdgeInsets.all(16.0),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.center,
                mainAxisSize: MainAxisSize.max, //有效,外层Colum高度为整个屏幕
                children: <Widget>[
                  Container(
                    color: Colors.red,
                    child: Column(
                      mainAxisSize: MainAxisSize.max, //无效,内层Colum高度为实际高度
                      children: <Widget>[
                        Text("hello world "),
                        Text("I am Jack "),
                      ],
                    ),
                  )
                ],
              ),
            ),
          ),

效果图:

3.2、Column垂直占满空间

如果要让里面的Column占满外部Column,可以使用Expanded 组件:

Expanded( 
  child: Container(
    color: Colors.red,
    child: Column(
      mainAxisAlignment: MainAxisAlignment.center, //垂直方向居中对齐
      children: <Widget>[
        Text("hello world "),
        Text("I am Jack "),
      ],
    ),
  ),
)

效果图