很多场景下,子组件的尺寸和父容器的尺寸不一致——比如网络图片的宽高比和显示区域不同、文字长度在不同手机上有差异。FittedBox 负责把子组件缩放以适应父容器。
FittedBox(
fit: BoxFit.contain,
alignment: Alignment.center,
child: yourWidget,
)
fit:缩放模式(7 种)alignment:对齐方式(缩放后的内容在容器中的位置)clipBehavior:是否裁剪溢出内容等比例缩放,完整显示子组件。可能留白。
FittedBox(
fit: BoxFit.contain,
child: Container(width: 160, height: 100, color: Colors.blue),
)
等比例缩放,填满容器。可能会被裁剪。
FittedBox(
fit: BoxFit.cover,
clipBehavior: Clip.hardEdge,
child: Image.network('https://example.com/photo.jpg'),
)
不等比例拉伸,填满整个容器。内容比例会变形。
FittedBox(
fit: BoxFit.fill,
child: textWidget,
)
宽度对齐容器,高度自适应。
高度对齐容器,宽度自适应。
等比例缩小到容器内,但不会放大。适合大图适配小容器。
按子组件的原始尺寸显示,超出容器部分会被裁剪(如果设置了 clipBehavior)。
| 模式 | 比例保持 | 填满容器 | 可能留白 | 可能裁剪 |
|---|---|---|---|---|
| contain | 是 | 否 | 是 | 否 |
| cover | 是 | 是 | 否 | 是 |
| fill | 否 | 是 | 否 | 否 |
| fitWidth | 是 | 否 | 是(上下) | 是(上下) |
| fitHeight | 是 | 否 | 是(左右) | 是(左右) |
| scaleDown | 是 | 否 | 是 | 否 |
| none | — | 否 | 否 | 是 |
缩放后的内容在容器中的位置由 alignment 控制:
// 居中对齐(默认)
FittedBox(alignment: Alignment.center, child: ...)
// 左上角
FittedBox(alignment: Alignment.topLeft, child: ...)
// 右下角
FittedBox(alignment: Alignment.bottomRight, child: ...)
// 自定义
FittedBox(alignment: Alignment(0.5, -0.5), child: ...)
当 fit 模式可能导致子组件溢出容器时(比如 cover),clipBehavior 控制是否裁剪:
FittedBox(
fit: BoxFit.cover,
clipBehavior: Clip.hardEdge, // 裁剪溢出部分
child: imageWidget,
)
默认是 Clip.none,不裁剪。设为 Clip.hardEdge 会裁剪掉溢出部分,但是用了硬件加速,性能好。
FittedBox(
fit: BoxFit.contain,
child: Row(
children: [
Image.asset('icon.png', width: 24, height: 24),
SizedBox(width: 4),
Text('Flutter'),
],
),
)
FittedBox 包裹 Row 后,如果容器宽度不够,整个图文会等比例缩小,不会换行。
Container(
width: 100,
height: 100,
decoration: BoxDecoration(
color: Colors.grey[200],
borderRadius: BorderRadius.circular(8),
),
child: FittedBox(
fit: BoxFit.cover,
clipBehavior: Clip.hardEdge,
child: Image.network(userAvatarUrl),
),
)
Container(
width: 200,
child: FittedBox(
fit: BoxFit.scaleDown,
child: Text('这是一段很长的文字可能会超出容器宽度'),
),
)
文字不会换行,而是自动缩小到容器宽度内。适合标题过长时的保底方案。
Image 也支持 BoxFit:
Image.network(
'url',
fit: BoxFit.cover,
width: 200,
height: 100,
)
区别在于 Image.fit 只对图片生效,FittedBox 可以包裹任意组件。
FittedBox 默认 clipBehavior: Clip.none,如果子组件缩放到容器范围外,超出部分不会被裁剪。需要裁剪时手动设 clipBehavior: Clip.hardEdge。
BoxFit.contain 是等比例显示全部内容,如果容器宽高比和子组件不同,会在某个方向留白。需要填满容器的用 cover 或 fill。
FittedBox 需要知道子组件的具体尺寸才能缩放。如果子组件是 Column 且没有固定高度,FittedBox 会报布局错误。给 Column 包裹 IntrinsicHeight 或设置固定尺寸。
文字缩放后可能有锯齿或模糊,尤其是缩放比例不是 1.0 的时候。如果只是文字过长自适应,用 Text 的 overflow: TextOverflow.ellipsis 更合适:
Text(
'很长的文字',
overflow: TextOverflow.ellipsis,
maxLines: 1,
)
BoxFit.scaleDown 和 contain 类似,但子组件比容器小时不会放大。适合头像、图标——小图显示原大小,大图缩小到容器内。
一个 FittedBox 套另一个 FittedBox 会导致缩放链式叠加,结果很难控制。避免嵌套使用。
Flutter 3.27.4
Dart 3.6.2
DevEco Studio 6.1.0.830
HarmonyOS NEXT 6.1
原文作者:;如有侵权,请联系管理员删除。