Flutter布局

343 阅读3分钟

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 初始化时设定的宽高。

Contafner(e.png

如果我们只需要将子 Widget 设定间距,则可以使用另一个单子容器控件 Padding 进行内容填充:

padding Edreinsets.all(44.0).png

Center :其子 Widget 居中排列

Container(.png

多子 Widget 布局:Row、Column 与 Expanded

  • Row:按行水平排列
  • Column:按列垂直排列
  • Expanded:负责分配这些子 Widget 在布局方向(行 / 列)中剩余空间

children《Midsetl.png

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 位置的能力。使用方法参考如下:

Stackt.png

备注: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');
              }),
        ),
      ),
    );
  }
}