2
\$\begingroup\$

I'm trying to see if this RenderObject is well implemented or if it's doing something bad with respect to Flutter rendering algorithm, especially:

  1. Is it ok to call child!.getDryLayout inside the performLayout method?
  2. Is it ok to conditionally paint the child on the paint method?
  3. Is it really necessary to override computeDryLayout?

This widget works perfectly (it hides the child widget if there is not enough vertical space for it, no warnings or exceptions). Have I written this code correctly?

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
/// A widget that only renders its child if there is enough vertical space
/// to fully display it. If there is not enough height available, the child
/// is not rendered at all (takes zero space).
class RenderIfHeightFits extends SingleChildRenderObjectWidget {
 const RenderIfHeightFits({
 required super.child,
 super.key,
 });
 @override
 RenderObject createRenderObject(BuildContext context) {
 return RenderIfHeightFitsBox();
 }
}
/// The render object behind [RenderIfHeightFits].
/// It suppresses its child if the child’s desired height exceeds the available height.
class RenderIfHeightFitsBox extends RenderProxyBox {
 @override
 Size computeDryLayout(BoxConstraints constraints) {
 if (child == null) {
 return Size.zero;
 }
 final childSize = child!.getDryLayout(
 constraints.copyWith(maxHeight: double.infinity),
 );
 final fits = childSize.height <= constraints.maxHeight;
 return fits ? childSize : Size.zero;
 }
 @override
 void performLayout() {
 if (child == null) {
 size = Size.zero;
 return;
 }
 /// ───── Step 1: Measure the child's natural (unconstrained) height ─────
 ///
 /// We give the child loose height constraints (essentially unconstrained)
 /// so it can tell us how tall it *wants* to be.
 final desiredSize = child!.getDryLayout(
 constraints.copyWith(maxHeight: double.infinity),
 );
 final desiredHeight = desiredSize.height;
 /// ───── Step 2: Compare child's desired height with available space ─────
 ///
 /// If we have enough height, lay it out normally using the incoming constraints.
 if (desiredHeight <= constraints.maxHeight) {
 child!.layout(constraints, parentUsesSize: true);
 size = child!.size;
 } else {
 /// Not enough space: lay out the child as a zero-size box and take no space.
 child!.layout(BoxConstraints.tight(Size.zero));
 size = Size.zero;
 }
 }
 @override
 void paint(PaintingContext context, Offset offset) {
 /// Only paint the child if it has a non-zero size.
 if (child != null && size != Size.zero) {
 context.paintChild(child!, offset);
 }
 }
}
toolic
15.9k6 gold badges29 silver badges217 bronze badges
asked May 2 at 21:41
\$\endgroup\$

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.