Flutter提供了31种布局Widget,具体参考flutter布局方式。以下内容为常见Widget布局方式
单子 Widget 布局:Container、Padding 与 Center
Container 本身可以单独作为控件存在(比如单独设置背景色、宽高),也可以作为其他控件的父级存在:Container 可以定义布局过程中子 Widget 如何摆放,以及如何展示。
Container 计算宽高的时候,除了要考虑 width、height 参数以外,还要遵循父组件设置的尺寸约束(BoxConstraints)。
BoxContraints 主要有四个属性:minWidth、maxWidth、minHeight、maxHeight。父组件使用 BoxConstraints 来约束子组件可以显示的最小/最大尺寸。如果 Container 的 width/height 不在 constraints 的范围内的时候,显示的尺寸会被强制计算成一个符合 constraints 要求的值,而不再使用 Container 初始化时设定的宽高。
如果我们只需要将子 Widget 设定间距,则可以使用另一个单子容器控件 Padding 进行内容填充:
Center :其子 Widget 居中排列
多子 Widget 布局:Row、Column 与 Expanded
- Row:按行水平排列
- Column:按列垂直排列
- Expanded:负责分配这些子 Widget 在布局方向(行 / 列)中剩余空间
MainAxisAlignment:
MainAxisAlignment.spaceBetween:将自由空间均匀放置在孩子之间(左右widget靠边,中间等分) MainAxisAlignment.spaceAround: 控件两边都距离一样(中间距离是左右两边都一倍) MainAxisAlignment.spaceEvenly:左右字widget均匀分配空间,所有间距一样大小
对于Row或者Column。Flutter提供了根据坐标轴的布局方式。根据布局方向划分出主轴和纵轴:主轴,表示容器依次摆放子 Widget 的方向;纵轴,则是与主轴垂直的另一个方向。以Row为例:主轴方向 start 表示靠左对齐、center 表示横向居中对齐、end 表示靠右对齐、spaceEvenly 表示按固定间距对齐;而纵轴方向 start 则表示靠上对齐、center 表示纵向居中对齐、end 表示靠下对齐。
- 主轴:mainAxisAlignment
- 纵轴:crossAxisAlignment
对于主轴而言,Flutter 默认是让父容器决定其长度,即尽可能大,类似 Android 中的 match_parent。如果想让容器与子 Widget 在主轴上完全匹配,我们可以通过设置 Row 的 mainAxisSize 参数为 MainAxisSize.min,由所有子 Widget 来决定主轴方向的容器长度,即主轴方向的长度尽可能小,类似 Android 中的 wrap_content。
层叠 Widget 布局:Stack 与 Positioned
Stack 提供了层叠布局的容器,而 Positioned 则提供了设置子 Widget 位置的能力。使用方法参考如下:
备注:Positioned 控件只能在 Stack 中使用,在其他容器中使用会报错
FractionallySizedBox
用法与SizedBox类似,只不过FractionallySizedBox的宽高是百分比大小,widthFactor,heightFactor参数就是相对于父控件的比例。注意设置FractionallySizedBox宽高后,其子组件设置的宽高将不起作用(强制设置)
class AuthList extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('代码测试'),
centerTitle: true,
),
body: FractionallySizedBox(
widthFactor: 0.5, // 百分比 - 整个区域最大的宽度
heightFactor: 0.5, // 百分比 - 整个区域最大的高度
child: SizedBox.fromSize(
size: Size(300.0, 370.0), // 不起作用, 被 widthFactor 和 heightFactor 限制了.
child: RaisedButton(
color: Colors.pink,
child: Text('pressed',style: TextStyle(color: Colors.white),),
onPressed: () {
print('onPressed');
}),
),
),
);
}
}