开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第 6 天,点击查看活动详情
什么用
A widget that sizes its child to the child's maximum intrinsic width
先看代码中对组件的注释,让子组件的宽度为子组件的最大内在宽度。也就是当希望一个组件没有固定的大小时,让这个组件自己测量,得到一个最大的宽度。
场景 案例
希望达到的效果如下,title 和 content 宽度相同
编写代码如下
Widget buildBearWidget(int i) {
return Padding(
padding: EdgeInsets.all(8.0),
child: Container(
color: Colors.white,
child: Column(
children: [
Container(
color: Colors.grey,
child: Text('title ' * i),
),
Container(
color: Colors.indigoAccent,
child: ConstrainedBox(
constraints: const BoxConstraints(
minHeight: 50,
minWidth: 50,
),
child: Text('content ' * i)),
),
],
),
),
);
}
实际运行效果为
图中 灰色背景为 title,蓝色背景为 content
可以看到 title 和 content 的宽度不一致,如果希望 title 和 content 宽度一致,那么尝试设置 两个widget 的宽度都与 父相同,添加
width: double.infinity
得到的效果为
Title 和 content 的宽度相同了,也和父widget宽度相同了,但是父 widget 也被撑满了更高的一层widget。
父widget 和 期待的效果不同,需要父 widget 为 子 widget 的最大宽度。
效果符合预期了
定义
/// A widget that sizes its child to the child's maximum intrinsic width.
/// 让孩子的大小为子组件的最大内在宽度的组件
///
/// This class is useful, for example, when unlimited width is available and
/// you would like a child that would otherwise attempt to expand infinitely to
/// instead size itself to a more reasonable width.
///
/// 什么时候有用:未限制宽度,一个字组件试图扩展到无限宽度,
/// 但是你让子组件的大小为一个更合适的宽度
///
/// The constraints that this widget passes to its child will adhere to the
/// parent's constraints, so if the constraints are not large enough to satisfy
/// the child's maximum intrinsic width, then the child will get less width
/// than it otherwise would. Likewise, if the minimum width constraint is
/// larger than the child's maximum intrinsic width, the child will be given
/// more width than it otherwise would.
///
/// If [stepWidth] is non-null, the child's width will be snapped to a multiple
/// of the [stepWidth]. Similarly, if [stepHeight] is non-null, the child's
/// height will be snapped to a multiple of the [stepHeight].
///
/// This class is relatively expensive, because it adds a speculative layout
/// pass before the final layout phase. Avoid using it where possible. In the
/// worst case, this widget can result in a layout that is O(N²) in the depth of
/// the tree.
这个类相对昂贵,因为他在最终布局前添加了推测布局传递,了最差情况下可能会生成 O(N^2)深度的 layout 树
注意事项
耗费性能 - 原因未抽时间分析,目前体验无卡顿
原理:
RenderIntrinsicWidth 中 获取子 widget 的内在宽度
Size _computeSize({required ChildLayouter layoutChild, required BoxConstraints constraints}) {
if (child != null) {
if (!constraints.hasTightWidth) {
final double width = child!.getMaxIntrinsicWidth(constraints.maxHeight);
assert(width.isFinite);
constraints = constraints.tighten(width: _applyStep(width, _stepWidth));
}
if (_stepHeight != null) {
final double height = child!.getMaxIntrinsicHeight(constraints.maxWidth);
assert(height.isFinite);
constraints = constraints.tighten(height: _applyStep(height, _stepHeight));
}
return layoutChild(child!, constraints);
} else {
return constraints.smallest;
}
}