setFullExtent method

void setFullExtent(
  1. TKey key,
  2. double extent
)

Stores the measured full extent for a node.

Called by the render object after laying out a child.

Implementation

void setFullExtent(TKey key, double extent) {
  final oldExtent = _fullExtentOf(key);

  // Check operation group member — resolve unknown extents
  final groupKey = _operationGroupOf(key);
  if (groupKey != null) {
    final group = _operationGroups[groupKey];
    if (group != null) {
      final member = group.members[key];
      if (member != null) {
        if (member.targetExtent == _unknownExtent) {
          final status = group.controller.status;
          if (status == AnimationStatus.forward ||
              status == AnimationStatus.completed) {
            member.targetExtent = extent;
          }
        } else if (oldExtent != extent && !member.targetIsCaptured) {
          // Update only when targetExtent is the natural full
          // reference. Captured targets (set when this member was
          // pulled in from a mid-flight standalone or other source)
          // represent the visual extent at capture time, not the
          // natural full size — overwriting them here would make a
          // freshly-inserted row caught at progress=0 mid-enter
          // suddenly read at the full natural size during the
          // parent's collapse.
          //
          // targetExtent is the "fully expanded" reference (value=1);
          // startExtent is always 0 (fully collapsed). Update targetExtent
          // regardless of direction — during reverse (collapsing), setting
          // startExtent = extent would make the lerp return `extent` at
          // value=0 instead of 0, so the node would never collapse to zero.
          member.targetExtent = extent;
        }
      }
    }
    _setFullExtentRaw(key, extent);
    if (oldExtent != extent) _scroll.invalidatePrefix();
    return;
  }

  if (oldExtent == extent) {
    // Still resolve unknown targets even when extent matches.
    final animation = _standaloneAt(key);
    if (animation != null && animation.targetExtent == _unknownExtent) {
      if (animation.type == AnimationType.entering) {
        animation.targetExtent = extent;
        animation.updateExtent(animationCurve);
      }
    }
    return;
  }
  _setFullExtentRaw(key, extent);
  _scroll.invalidatePrefix();
  // If node is animating with unknown target, update the animation
  final animation = _standaloneAt(key);
  if (animation != null && animation.targetExtent == _unknownExtent) {
    // Now we know the real extent - update the animation state
    if (animation.type == AnimationType.entering) {
      animation.targetExtent = extent;
      animation.updateExtent(animationCurve);
    }
  }
  // Also update if extent changed and node is animating
  else if (animation != null) {
    if (animation.type == AnimationType.entering) {
      animation.targetExtent = extent;
      animation.updateExtent(animationCurve);
    }
    // For exiting animations, startExtent is historical (the extent at the
    // moment the exit began, potentially captured mid-transition from an
    // earlier source). Overwriting it with the freshly-measured full extent
    // would retroactively rewrite where the exit started and jump the row
    // forward on the next tick. Let the exit run from its original
    // startExtent to 0 without interference.
  }
}