Flutter 弹性布局 Flex

Flutter 弹性布局 Flex_第1张图片
新建项目-4.png

Flex 有一个必填参数:direction,用于确定主轴的方向,然后就可以在 children 里写 子Widget

class Flex extends MultiChildRenderObjectWidget {
  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 children = const [],
  }) : assert(direction != null),
       assert(mainAxisAlignment != null),
       assert(mainAxisSize != null),
       assert(crossAxisAlignment != null),
       assert(verticalDirection != null),
       assert(crossAxisAlignment != CrossAxisAlignment.baseline || textBaseline != null),
       super(key: key, children: children);
    ...
}

因为Row继承于Flex所有大部分属性Flex都是一样的.具体看Row的总结

Flutter Row

Flexible 与 Expanded

以下内容来自:

Flutter 布局 Widget —— 弹性布局

如果当 Flex 里的内容过长,超过主轴的大小,例如如下的代码:

Flex(
  direction: Axis.horizontal,
  mainAxisAlignment: MainAxisAlignment.start,
  children: [
    Text('Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!')
  ],
)
image.png

为了避免 子Widget 在 Row、Column、Flex 中超界,就可以使用 Flexible 与 Expanded。Flexible 与 Expanded 可以让 Row、Column、Flex 的 子Widget 具有弹性能力。

比如上面的例子用 Flexible 或 Expended 来改写:

Flexible(
  child: Text(
      'Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!'
  ),
)
image.png
Expanded(
  child: Text(
      'Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!'
  ),
),
image.png

用 Flexible 与 Expanded 来包 子Widget,当 子Widget 要超过主轴的大小时,会自动换行,但是 Flexible 与 Expanded 也有不同的地方,Expanded 是 Flexible 的子类。

Flexible 与 Expanded 区别

Flexible构造函数:

const Flexible({
    Key key,
    this.flex = 1,  //此 Widget 的弹性因子
    this.fit = FlexFit.loose, //如何分配 弹性Widget 在可用空间里的大小
    @required Widget child,
  }) : super(key: key, child: child);

Expanded 构造函数:

const Expanded({
    Key key,
    int flex = 1,   //此 Widget 的弹性因子
    @required Widget child,
  }) : super(key: key, flex: flex, fit: FlexFit.tight, child: child);

可以明显看到,Flexible 和 Expanded 的 fit 参数不同,Flexible 的 fit 是 FlexFit.loose,Expanded 的 fit 参数是 FlexFit.tight。所以,当还有剩余空间时,Expanded 会占满剩余的所有空间,而 Flexible 只会占用自身大小的空间。

Flexible(
    child: Container(
      color: Colors.yellow,
      child: Text('使用 Flexible 来包裹 子Widget'),
    ),
  ),
Expanded(
    child: Container(
      color: Colors.yellow,
      child: Text('使用 Expanded 来包裹 子Widget'),
    ),
  ),
Flutter 弹性布局 Flex_第2张图片
image.png

Flexible 会占用自身大小,而 Expanded 会占满全屏幕。

总结

Flexible 与 Expanded 可以让 Row、Column、Flex 的 子Widget 具有弹性能力,当 子Widget 要超过主轴的大小时,会自动换行,当还有剩余空间时,Expanded 会占满剩余的所有空间,而 Flexible 只会占用自身大小的空间。

Fexible 和 Expanded 的 flex 弹性系数

Fexible 和 Expanded 还有一个很重要的参数:flex,flex 为弹性系数,其布局过程如下:

  1. 如果 flex 为0或null,则 child 是没有弹性的,称为 非弹性子Widget,非弹性子Widget 的大小就是其本身的大小,不会被扩展去占用多余的空间。
  2. 如果 flex 大于0,child 是有弹性的,称为 弹性子Widget,首先会计算出第一步所有 flex为0或null 的 子Widget 的大小,然后会会按照 弹性子Widget的flex 占 所有弹性子Widget的flex 总和 的比例来分割主轴的空闲空间。
child: Flex(
    direction: Axis.horizontal,
    mainAxisAlignment: MainAxisAlignment.start,
    children: [
      Flexible(
        flex: 1,
        child: Container(
          height: 30,
          width: 30,
          color: Colors.yellow,
        ),
      ),
      Flexible(
        flex: 2,
        child: Container(
          height: 30,
          width: 30,
          color: Colors.red,
        ),
      ),
      Flexible(
        flex: 1,
        child: Container(
          height: 30,
          width: 30,
          color: Colors.orange,
        ),
      ),
    ],
  ),

三个 Flexible 的 flex : 1、2、1

image.png

因为 子Widget 的宽度是固定的,所以 Flexible 只会占用本身的大小。

child: Flex(
    direction: Axis.horizontal,
    mainAxisAlignment: MainAxisAlignment.start,
    children: [
      Expanded(
        flex: 1,
        child: Container(
          height: 30,
          width: 30,
          color: Colors.yellow,
        ),
      ),
      Expanded(
        flex: 2,
        child: Container(
          height: 30,
          width: 30,
          color: Colors.red,
        ),
      ),
      Expanded(
        flex: 1,
        child: Container(
          height: 30,
          width: 30,
          color: Colors.orange,
        ),
      ),
    ],
  ),

Expanded 包裹三个宽高都为 30 的色块,并设置 flex 为 1、2、1

image.png

虽然三个色块的宽度是固定的,但是 Expanded 还是按照比例瓜分了剩余的全部空间。

你可能感兴趣的:(Flutter 弹性布局 Flex)