可伸缩
Row 和 Column可以通过mainAxisAlignment 和 crossAxisAlignment 对children进行布局,但child的大小是固定的。固定大小的小部件被认为是 不灵活的 因为它们布局后无法自我调整大小。
Flexible 和Expanded包裹的对象可以根据剩余空间自动伸缩。
配置属性
Flexible 属性:
- flex 将自身的 flex 因子与其他的比较,以决定自身占剩余空间的比例。
- fit 决定 Flexible 的 widget 是否能够填充所有剩余空间。
FlexFit.loose使用 widget 的自身作为首选大小。 (默认情况下 )
FlexFit.tight强制 widget 充满所有剩余空间。
Expanded 属性:
- flex 将自身的 flex 因子与其他的比较,以决定自身占剩余空间的比例。
限制条件
Flexible组件必须是Row、Column、Flex等组件的后裔,并且从Flexible到它封装的Row、Column、Flex的路径必须只包括StatelessWidgets或StatefulWidgets组件(不能是其他类型的组件,像RenderObjectWidgets)。
Expanded组件必须用在Row、Column、Flex内,并且从Expanded到封装它的Row、Column、Flex的路径必须只包括StatelessWidgets或StatefulWidgets组件(不能是其他类型的组件,像RenderObjectWidget,它是渲染对象,不再改变尺寸了,因此Expanded不能放进RenderObjectWidget)。
Flux是Row和Column的父组件,灵活强大。但是大部分场景都可以使用Row和Column满足条件,更加便利。
区别
Flexible根据剩余空间,调整组件的大小,但是不要求组件充满parent。
Expanded要求必须填充满parent。
Flexible实例
Flexible有两个:
第一个Flexible绘制的时候,空间被前三个BlueBox占据了一部分,余下的空间如下图所示。在剩下的空间里,一共flex=1+1=2.第一个Flexible的flex=1.所以第一个Flexible占据剩下的二分之一。
第二个Flexible大小还是BlueBox的大小。因为fit: FlexFit.loose,所以选择采用子组件的大小。
计算公式: remainingSpace * (flex / totalOfAllFlexValues)
remainingSpace:除去固定大小后的空间。
totalOfAllFlexValues:所有的flex值和。
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Row(
children: [
BlueBox(),
BlueBox(),
BlueBox(),
Flexible(
fit: FlexFit.loose,
flex: 1,
child: Container(
height: 50,
decoration: BoxDecoration(
color: Colors.blue,
border: Border.all(),
),
),
),
Flexible(
fit: FlexFit.loose,
flex: 1,
child: BlueBox(),
),
],
);
}
}
class BlueBox extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
width: 50,
height: 50,
decoration: BoxDecoration(
color: Colors.blue,
border: Border.all(),
),
);
}
}
修改组件的布局方式,让Flexible和固定的交叉布局。如下图,第二个Flexible的大小。
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Row(
children: [
Flexible(
fit: FlexFit.loose,
flex: 1,
child: BlueBox(),
),
BlueBox(),
BlueBox(),
Flexible(
fit: FlexFit.loose,
flex: 2,
child: Container(
height: 50,
decoration: BoxDecoration(
color: Colors.blue,
border: Border.all(),
),
),
),
Flexible(
fit: FlexFit.loose,
flex: 1,
child: BlueBox(),
),
],
);
}
}
Expanded实例
Expanded会填充满剩余的空间。
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Row(
children: [
BlueBox(),
Expanded(flex: 3, child:BlueBox()),
Expanded(flex: 2, child: BlueBox()),
BlueBox(),
],
);
}
}
class BlueBox extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
width: 50,
height: 50,
decoration: BoxDecoration(
color: Colors.blue,
border: Border.all(),
),
);
}
}