onLayout static method

Future<Size?> onLayout(
  1. GlobalKey<State<StatefulWidget>> key, {
  2. int maxWaitFrames = 20,
  3. int stabilityFrames = 2,
  4. bool waitForEndOfFrame = true,
})

Waits for the widget associated with key to obtain a non-zero size and remain stable for stabilityFrames consecutive frame checks. Returns the final Size or null if not resolved within maxWaitFrames.

Implementation

static Future<Size?> onLayout(
  GlobalKey key, {
  int maxWaitFrames = 20,
  int stabilityFrames = 2,
  bool waitForEndOfFrame = true,
}) async {
  assert(stabilityFrames >= 1);
  final binding = WidgetsBinding.instance;
  int remaining = maxWaitFrames;
  Size? lastSize;
  int stableCount = 0;
  while (remaining-- > 0) {
    if (waitForEndOfFrame) {
      await binding.endOfFrame;
    } else {
      // microtask flush then next frame
      await Future.delayed(Duration.zero);
    }
    // Fetch and use the RenderObject directly without storing a BuildContext
    // variable (avoids use_build_context_synchronously lint false-positive).
    final renderObject = key.currentContext?.findRenderObject();
    if (renderObject is! RenderBox) continue;
    final size = renderObject.hasSize ? renderObject.size : null;
    if (size == null || size == Size.zero) {
      stableCount = 0;
      continue;
    }
    if (lastSize == size) {
      stableCount++;
      if (stableCount >= stabilityFrames) return size;
    } else {
      lastSize = size;
      stableCount = 1; // First stable observation.
      if (stableCount >= stabilityFrames) return size;
    }
  }
  return null; // Timed out.
}