\$\begingroup\$
\$\endgroup\$
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:
- Is it ok to call
child!.getDryLayoutinside theperformLayoutmethod? - Is it ok to conditionally paint the child on the
paintmethod? - 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
Ademir Villena Zevallos
213 bronze badges
You must log in to answer this question.
default