Skip to content

Commit f194cd3

Browse files
Make FittedBox not throw when child has zero size. (#150430)
fix flutter/flutter#135082 , fix flutter/flutter#139539 , fix flutter/flutter#142910 Before, `FittedBox` would throw when child size is zero, unless the constraint is tight and fit is not `BoxFit.scaleDown`.
1 parent a3c7094 commit f194cd3

File tree

4 files changed

+49
-20
lines changed

4 files changed

+49
-20
lines changed

packages/flutter/lib/src/rendering/box.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,10 +322,12 @@ class BoxConstraints extends Constraints {
322322
return result;
323323
}
324324

325+
if (size.isEmpty) {
326+
return constrain(size);
327+
}
328+
325329
double width = size.width;
326330
double height = size.height;
327-
assert(width > 0.0);
328-
assert(height > 0.0);
329331
final double aspectRatio = width / height;
330332

331333
if (width > maxWidth) {

packages/flutter/lib/src/rendering/proxy_box.dart

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2711,24 +2711,6 @@ class RenderFittedBox extends RenderProxyBox {
27112711
if (child != null) {
27122712
final Size childSize = child!.getDryLayout(const BoxConstraints());
27132713

2714-
// During [RenderObject.debugCheckingIntrinsics] a child that doesn't
2715-
// support dry layout may provide us with an invalid size that triggers
2716-
// assertions if we try to work with it. Instead of throwing, we bail
2717-
// out early in that case.
2718-
bool invalidChildSize = false;
2719-
assert(() {
2720-
if (RenderObject.debugCheckingIntrinsics && childSize.width * childSize.height == 0.0) {
2721-
invalidChildSize = true;
2722-
}
2723-
return true;
2724-
}());
2725-
if (invalidChildSize) {
2726-
assert(debugCannotComputeDryLayout(
2727-
reason: 'Child provided invalid size of $childSize.',
2728-
));
2729-
return Size.zero;
2730-
}
2731-
27322714
switch (fit) {
27332715
case BoxFit.scaleDown:
27342716
final BoxConstraints sizeConstraints = constraints.loosen();

packages/flutter/test/rendering/box_constraints_test.dart

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,4 +182,17 @@ void main() {
182182
expect(constraints, const BoxConstraints(minWidth: 1, maxWidth: 2, minHeight: 3, maxHeight: 4));
183183
});
184184

185+
test('BoxConstraints.constrainSizeAndAttemptToPreserveAspectRatio can handle empty size', () {
186+
const BoxConstraints constraints = BoxConstraints(
187+
minWidth: 10.0,
188+
maxWidth: 20.0,
189+
minHeight: 10.0,
190+
maxHeight: 20.0,
191+
);
192+
const Size unconstrainedSize = Size(15.0, 0.0);
193+
final Size constrainedSize = constraints.constrainSizeAndAttemptToPreserveAspectRatio(
194+
unconstrainedSize,
195+
);
196+
expect(constrainedSize, const Size(15.0, 10.0));
197+
});
185198
}

packages/flutter/test/widgets/fitted_box_test.dart

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,38 @@ void main() {
605605
await tester.tap(find.byType(FittedBox), warnIfMissed: false);
606606
expect(tester.takeException(), isNull);
607607
});
608+
609+
// Regression test for https://github.com/flutter/flutter/issues/135082
610+
testWidgets('FittedBox with zero size child does not throw', (WidgetTester tester) async {
611+
await tester.pumpWidget(
612+
const Center(
613+
child: SizedBox(
614+
height: 200.0,
615+
width: 200.0,
616+
child: FittedBox(
617+
fit: BoxFit.scaleDown,
618+
child: SizedBox.shrink(),
619+
),
620+
),
621+
),
622+
);
623+
expect(tester.takeException(), isNull);
624+
625+
await tester.pumpWidget(
626+
Center(
627+
child: ConstrainedBox(
628+
constraints: const BoxConstraints(
629+
maxWidth: 200.0,
630+
maxHeight: 200.0,
631+
),
632+
child: const FittedBox(
633+
child: SizedBox.shrink(),
634+
),
635+
),
636+
),
637+
);
638+
expect(tester.takeException(), isNull);
639+
});
608640
}
609641

610642
List<Type> getLayers() {

0 commit comments

Comments
 (0)