RenderBox 的干布局支持
概述
#RenderBox
协议中新增了一个名为 computeDryLayout
的方法。RenderBox
的子类应实现此方法,以便在进行固有计算时,根据一组 BoxConstraints
正确报告其所需尺寸。实现了 computeDryLayout
的子类不再需要重写 performResize
。
背景
#RenderBox
协议中新增了 computeDryLayout
方法,用于正确计算带有 WidgetSpan
子项的 RenderParagraph
和 RenderWrap
的固有尺寸。此方法接收一组 BoxConstraints
,并应在不改变任何内部状态的情况下计算出 RenderBox
的最终尺寸。它本质上是 performLayout
的一次“干运行”(dry run),只计算最终尺寸,而不放置子项。computeDryLayout
方法是固有协议(intrinsics protocol)的一部分(另请参见 RenderBox.computeMinIntrinsicWidth
等方法)。
变更说明
#如果 RenderBox
的子类用作可能查询其子项固有尺寸的 RenderObject
的后代,则需要重写新的 computeDryLayout
方法。执行此操作的 widget 示例包括 IntrinsicHeight
和 IntrinsicWidth
。
RenderBox.performResize
的默认实现也使用 computeDryLayout
计算出的尺寸来执行大小调整。因此,不再需要重写 performResize
。
迁移指南
#已经重写 performResize
的子类可以通过简单地将函数签名从 void performResize()
更改为 Size computeDryLayout(BoxConstraints constraints)
,并返回计算出的尺寸而不是将其赋值给 size
setter 来进行迁移。旧的 performResize
实现可以删除。
迁移前的代码
@override
void performResize() {
size = constraints.biggest;
}
迁移后的代码
// This replaces the old performResize method.
@override
Size computeDryLayout(BoxConstraints constraints) {
return constraints.biggest;
}
如果子类没有重写 performResize
,则必须从 performLayout
方法中提取 computeDryLayout
的实现。基本上,computeDryLayout
需要完成 performLayout
为确定 RenderBox
尺寸所做的所有工作。然而,它不是将其赋值给 size
setter,而是返回计算出的尺寸。如果 computeDryLayout
需要知道其子项的尺寸,它必须通过调用子项的 getDryLayout
来获取该尺寸,而不是调用 layout
。
如果由于某种原因无法计算干布局,computeDryLayout
必须在断言(assert)内部调用 debugCannotComputeDryLayout
并返回一个虚拟尺寸 const Size(0, 0)
。例如,如果 RenderBox
的尺寸取决于其子项的基线指标,则无法计算干布局。
@override
Size computeDryLayout(BoxConstraints constraints) {
assert(debugCannotComputeDryLayout(
reason: 'Layout requires baseline metrics, which are only available after a full layout.'
));
return const Size(0, 0);
}
时间线
#已发布版本:1.25.0-4.0.pre
稳定版本:2.0.0
参考资料
#API 文档
RenderBox
computeMinInstrinsicWidth
computeDryLayout
getDryLayout
performResize
RenderWrap
RenderParagraph
相关问题
相关 PR