Flutter 中 SizedBox、FractionallySizedBox、LimitedBox、AspectRatio 的使用详解

这是我参与更文挑战的第26天,活动详情查看: 更文挑战

前言

在日常的 Flutter 页面开发当中,会涉及到各种大小的调配,有时我们希望高度固定,宽度缩放,有时希望宽高按照一定比例来展示,有时希望按照百分比来设置宽高,那么今天我们就看看在 Flutter 当中 Box 大小的设置。

SizedBox(大小盒子)

这个我们使用的比较多,比如设置一个按钮的大小,设置间隔宽度,设置间隔高度等,使用起来比较简单设置宽高即可。

SizedBox(
  height: 30,
  width: 30,
)
复制代码
  • 设置按钮大小
SizedBox(
  height: 100,
  width: 100,
  child: ElevatedButton(
    onPressed: () {},
    child: Text('点击'),
  ),
)
复制代码

image.png

  • 代替设置间距
Row(
  children: [
    Expanded(child: BoxWidget()),
    // 设置间距
    SizedBox(width: 20),
    Expanded(child: BoxWidget()),
  ],
)
复制代码

image.png

Column(
  children: [
    Expanded(child: BoxWidget()),
    // 设置间距
    SizedBox(height: 20),
    Expanded(child: BoxWidget()),
  ],
)
复制代码

image.png

其他几种快捷函数

  • SizedBox.expand (展开到最大,宽高都是无限大)

image.png

SizedBox.expand(
  child: ElevatedButton(
    onPressed: () {},
    child: Text('点击'),
  ),
)
复制代码
  • SizedBox.shrink(收缩,宽高都是 0)

image.png

SizedBox.shrink()
复制代码

还记得我们之前聊的 Spacer 吗?他内部就使用到了 SizedBox.shrink()
image.png

FractionallySizedBox(比例大小盒子)

在实际项目中我们有按照一定比例展示的需求,这时如果我们进行动态计算然后刷新就比较麻烦且低效,Flutter 为我们考虑到了这点,可以使用这个 Widget 来进行嵌套设置即可。

  • widthFactor 宽度占比
FractionallySizedBox(
  widthFactor: 1,
  child: BoxWidget(text: '1'),
),
SizedBox(height: 10),
FractionallySizedBox(
  widthFactor: 0.7,
  child: BoxWidget(text: '0.7'),
),
SizedBox(height: 10),
FractionallySizedBox(
  widthFactor: 0.4,
  child: BoxWidget(text: '0.4'),
),
复制代码

image.png

  • widthFactor 宽度比例
SizedBox(
  height: 100,
  child: FractionallySizedBox(
    heightFactor: 1,
    child: BoxWidget(text: '1'),
  ),
),
SizedBox(height: 10),
SizedBox(
  height: 100,
  child: FractionallySizedBox(
    heightFactor: 0.7,
    child: BoxWidget(text: '0.7'),
  ),
),
SizedBox(height: 10),
SizedBox(
  height: 100,
  child: FractionallySizedBox(
    heightFactor: 0.4,
    child: BoxWidget(text: '0.4'),
  ),
),
复制代码

image.png

LimitedBox(限制盒子)

上面的 Box 只可以指定固定的高度,有时我们在列表中想让高度随着子项的高度来显示,而不仅仅是一个统一的高度,这时就比较有难度了,幸亏 Flutter 帮我们做了这个 Widget 就可以解决这个问题。

  • maxHeight (最大高度)
LimitedBox(
  // 设置最大高度
  maxHeight: 100,
  child: FractionallySizedBox(
    heightFactor: 1,
    child: BoxWidget(text: '1'),
  ),
),
SizedBox(height: 10),
LimitedBox(
  maxHeight: 100,
  child: FractionallySizedBox(
    heightFactor: 0.7,
    child: BoxWidget(
      text: '0.7',
      height: 100,
    ),
  ),
),
SizedBox(height: 10),
LimitedBox(
  maxHeight: 100,
  child: FractionallySizedBox(
    heightFactor: 0.4,
    child: BoxWidget(
      text: '0.4',
    ),
  ),
),
复制代码

image.png
对比上面的效果,我们的子项已经自动适应了对应的高度。

  • maxWidth(最大宽度)
LimitedBox(
  // 设置最大宽度
  maxWidth: 100,
  maxHeight: 100,
  child: FractionallySizedBox(
    heightFactor: 0.7,
    child: BoxWidget(
      text: '0.7',
      height: 100,
    ),
  ),
),
SizedBox(height: 10),
LimitedBox(
  maxWidth: 100,
  maxHeight: 100,
  child: FractionallySizedBox(
    heightFactor: 0.4,
    child: BoxWidget(
      text: '0.4',
    ),
  ),
),
SizedBox(height: 10),
LimitedBox(
  maxWidth: 100,
  maxHeight: 100,
  child: SizedBox(
    height: 200,
    child: BoxWidget(text: '0.4'),
  ),
)
复制代码

image.png
为啥没有生效呢?

因为我们这里外层是 Column ,在竖直方向上是无约束的,在水平方向上最大约束就是屏幕宽度
然后 LimitedBox 是仅会在无约束的情况下才会生效的。

AspectRatio(宽高比盒子)

在项目中,比如签名画布的适配、Banner 图等都是需要按照宽高比来适配的,如果自己计算就比较麻烦些,这时使用 AspectRatio 就非常方便了。

AspectRatio(
  aspectRatio: 16 / 3,
  child: BoxWidget(
    text: '16 / 3',
  ),
),
SizedBox(height: 10),
AspectRatio(
  aspectRatio: 16 / 9,
  child: BoxWidget(
    text: '16 / 9',
  ),
)
复制代码

image.png

源码仓库

基于 Flutter ? 最新版本

参考链接

关注专栏

  • 此文章已收录到下面? 的专栏,可以直接关注
  • 更多文章继续阅读|系列文章持续更新

? 欢迎点赞➕收藏➕关注,有任何问题随时在下面?评论,我会第一时间回复哦

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享