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!')
],
)
为了避免 子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!'
),
)
Expanded(
child: Text(
'Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!Flutter!'
),
),
用 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'),
),
),
Flexible 会占用自身大小,而 Expanded 会占满全屏幕。
总结
Flexible 与 Expanded 可以让 Row、Column、Flex 的 子Widget 具有弹性能力,当 子Widget 要超过主轴的大小时,会自动换行,当还有剩余空间时,Expanded 会占满剩余的所有空间,而 Flexible 只会占用自身大小的空间。
Fexible 和 Expanded 的 flex 弹性系数
Fexible 和 Expanded 还有一个很重要的参数:flex
,flex 为弹性系数,其布局过程如下:
- 如果 flex 为0或null,则 child 是没有弹性的,称为 非弹性子Widget,非弹性子Widget 的大小就是其本身的大小,不会被扩展去占用多余的空间。
- 如果 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
因为 子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
虽然三个色块的宽度是固定的,但是 Expanded 还是按照比例瓜分了剩余的全部空间。