概述

#

RenderBox 协议中新增了一个名为 computeDryLayout 的方法。RenderBox 的子类应实现此方法,以便在进行固有计算时,根据一组 BoxConstraints 正确报告其所需尺寸。实现了 computeDryLayout 的子类不再需要重写 performResize

背景

#

RenderBox 协议中新增了 computeDryLayout 方法,用于正确计算带有 WidgetSpan 子项的 RenderParagraphRenderWrap 的固有尺寸。此方法接收一组 BoxConstraints,并应在不改变任何内部状态的情况下计算出 RenderBox 的最终尺寸。它本质上是 performLayout 的一次“干运行”(dry run),只计算最终尺寸,而不放置子项。computeDryLayout 方法是固有协议(intrinsics protocol)的一部分(另请参见 RenderBox.computeMinIntrinsicWidth 等方法)。

变更说明

#

如果 RenderBox 的子类用作可能查询其子项固有尺寸的 RenderObject 的后代,则需要重写新的 computeDryLayout 方法。执行此操作的 widget 示例包括 IntrinsicHeightIntrinsicWidth

RenderBox.performResize 的默认实现也使用 computeDryLayout 计算出的尺寸来执行大小调整。因此,不再需要重写 performResize

迁移指南

#

已经重写 performResize 的子类可以通过简单地将函数签名从 void performResize() 更改为 Size computeDryLayout(BoxConstraints constraints),并返回计算出的尺寸而不是将其赋值给 size setter 来进行迁移。旧的 performResize 实现可以删除。

迁移前的代码

dart
  @override
  void performResize() {
     size = constraints.biggest;
  }

迁移后的代码

dart
  // 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 的尺寸取决于其子项的基线指标,则无法计算干布局。

dart
  @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 文档

相关问题

相关 PR