4.3 弹性布局(Flex)
Flex弹性布局,是常见的一种布局,他允许盒子按照一定比例来分配空间。
Flex
Flex组件可以沿着水平或者垂直方向排列组件,如果你知道主轴方向,使用Row或Column可能会更方便点,因为Row和Column都是继承Flex,参数基本相同,所以Flex可以用的地方,基本Row和Column都可以满足要求。
 Flex({
    Key key,
    @required this.direction,
    this.mainAxisAlignment = MainAxisAlignment.start,
    this.mainAxisSize = MainAxisSize.max,
    this.crossAxisAlignment = CrossAxisAlignment.center,
    this.textDirection,
    this.verticalDirection = VerticalDirection.down,
    this.textBaseline,
    List<Widget> children = const <Widget>[],
  })
direction: 指定Axis.vertical它就是Column,指定为Axis.horizontal它就是Row.mainAxisAlignment: 主轴的排列位置,如果文本方向是TextDirection.ltr,start,按照从左向右的开始方向排列,否则从右向左排列。center是按照中间向两边排列,end是按照从结尾向开始方向排列。spaceBetween是两个子组件间隔一致。spaceEvenly是所有的空隙一致。spaceAround开始和结束是中间的间隙的一半。crossAxisAlignment副轴方向,和主轴方向类似,start是排列在开始位置。end排列在底部。center排列在副轴中间。baseline根据基线排列,stretch要求他的子组件副轴方向充满父组件。
效果图:
展示了主轴的常用的效果:

Expanded
可以按照比例扩展Row或者Column、Flex的所占空间。
Expanded({
    Key key,
    int flex = 1,
    @required Widget child,
  })
例子:
Container(
height: 30,
child: Row(children: <Widget>[
  Expanded(
    flex: 1,
    child: Container(
      color: Colors.red,
    ),
  ),
  Expanded(
    flex: 2,
    child: Container(
      color: Colors.orange,
    ),
  ),
  Expanded(
    flex: 3,
    child: Container(
      color: Colors.blue,
    ),
  )
]))
效果:

Spacer
const Spacer({Key key, this.flex = 1})
源码也很简单,其实是封装了Expanded,主动添加了一个大小是0,0的SizedBox.shrink().
例子:
Container(
    height: 30,
    child: Row(children: <Widget>[
      Container(
        width: 50,
        color: Colors.red,
      ),
      Spacer(
        flex: 1,
      ),
      Container(
        width: 50,
        color: Colors.red,
      ),
      Spacer(
        flex: 2,
      ),
      Container(
        width: 50,
        color: Colors.red,
      ),
    ]))
效果:

实际应用
当我们想子组件随着用父组件变大而变大,屏幕变宽而变宽,那么请使用弹性布局.
Row(
  children: <Widget>[
    Expanded(
      child: OutlineButton(
        child: Text('Expanded btn'),
      ),
    )
  ],
),
OutlineButton(
  child: Text('btn'),
),
效果:

如果距离左侧 或者右侧边距20px呢?
Row(
  children: <Widget>[
    SizedBox(
      width: 20,
    ),
    Expanded(
      child: OutlineButton(
        child: Text('Expanded btn'),
      ),
    ),
    SizedBox(
      width: 20,
    ),
  ],
)
效果图:

总结:
 如果横着排列请用Row,如果横着有些随着屏幕变宽也变宽,使用Row+Expanded,如果固定间隔请使用SizedBox,如果间隔按照比例分配,请用Spacer
弹性布局比较简单,多用才能有更深理解。