弹性布局(Flex)
弹性布局允许子组件按照一定比例来分配父容器空间。
Flex
因为Row和Column都继承自Flex,参数基本相同,所以能使用Flex的地方基本上都可以使用Row或Column。Flex本身功能是很强大的,它也可以和Expanded组件配合实现弹性布局。
Flex({
super.key,
required this.direction,////弹性布局的方向, Row默认为水平方向,Column默认为垂直方向
this.mainAxisAlignment = MainAxisAlignment.start,
this.mainAxisSize = MainAxisSize.max,
this.crossAxisAlignment = CrossAxisAlignment.center,
this.textDirection,
this.verticalDirection = VerticalDirection.down,
this.textBaseline, // NO DEFAULT: we don't know what the text's baseline should be
this.clipBehavior = Clip.none,
super.children,
})
Flex(
direction: Axis.horizontal,//vertical
children: [],
),
Expanded
Expanded 只能作为 Flex 的孩子(否则会报错),它可以按比例“扩伸”Flex子组件所占用的空间。因为 Row和Column 都继承自 Flex,所以 Expanded 也可以作为它们的孩子。
return Scaffold(
appBar: AppBar(title: const Text('线性布局'),),
body: Container(
child: Column(
children: [
//Flex的两个子widget按1:2来占据水平空间
Flex(
direction: Axis.horizontal,
children: [
Expanded(
flex: 1,
child: Container(
height: 30,
color: Colors.pink,
)
),
Expanded(
flex: 2,
child: Container(
height: 30,
color: Colors.green,
)
),
],
),
Padding(
padding: const EdgeInsets.only(top: 20),
child: SizedBox(
height: 100,
//Flex的三个子widget,在垂直方向按2:1:1来占用100像素的空间
child:Flex(
direction: Axis.vertical,
children: [
Expanded(
flex: 2,
child: Container(
height: 30.0,
color: Colors.red,
)
),
Spacer(flex: 1,),
Expanded(
flex: 1,
child: Container(
height: 30.0,
color: Colors.purple,
)
),
],
) ,
),
)
],
),
),
);
Spacer的功能是占用指定比例的空间,实际上它只是Expanded的一个包装类。源码:
class Spacer extends StatelessWidget {
/// Creates a flexible space to insert into a [Flexible] widget.
///
/// The [flex] parameter may not be null or less than one.
const Spacer({super.key, this.flex = 1})
: assert(flex != null),
assert(flex > 0);
/// The flex factor to use in determining how much space to take up.
///
/// The amount of space the [Spacer] can occupy in the main axis is determined
/// by dividing the free space proportionately, after placing the inflexible
/// children, according to the flex factors of the flexible children.
///
/// Defaults to one.
final int flex;
@override
Widget build(BuildContext context) {
return Expanded(
flex: flex,
child: const SizedBox.shrink(),
);
}
}