Skip to content

Commit

Permalink
Make FittedBox not throw when child has zero size. (#150430)
Browse files Browse the repository at this point in the history
fix #135082 , fix #139539 , fix #142910

Before, `FittedBox` would throw when child size is zero, unless the constraint is tight and fit is not `BoxFit.scaleDown`.
  • Loading branch information
PurplePolyhedron committed Jul 8, 2024
1 parent a3c7094 commit f194cd3
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 20 deletions.
6 changes: 4 additions & 2 deletions packages/flutter/lib/src/rendering/box.dart
Original file line number Diff line number Diff line change
Expand Up @@ -322,10 322,12 @@ class BoxConstraints extends Constraints {
return result;
}

if (size.isEmpty) {
return constrain(size);
}

double width = size.width;
double height = size.height;
assert(width > 0.0);
assert(height > 0.0);
final double aspectRatio = width / height;

if (width > maxWidth) {
Expand Down
18 changes: 0 additions & 18 deletions packages/flutter/lib/src/rendering/proxy_box.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2711,24 2711,6 @@ class RenderFittedBox extends RenderProxyBox {
if (child != null) {
final Size childSize = child!.getDryLayout(const BoxConstraints());

// During [RenderObject.debugCheckingIntrinsics] a child that doesn't
// support dry layout may provide us with an invalid size that triggers
// assertions if we try to work with it. Instead of throwing, we bail
// out early in that case.
bool invalidChildSize = false;
assert(() {
if (RenderObject.debugCheckingIntrinsics && childSize.width * childSize.height == 0.0) {
invalidChildSize = true;
}
return true;
}());
if (invalidChildSize) {
assert(debugCannotComputeDryLayout(
reason: 'Child provided invalid size of $childSize.',
));
return Size.zero;
}

switch (fit) {
case BoxFit.scaleDown:
final BoxConstraints sizeConstraints = constraints.loosen();
Expand Down
13 changes: 13 additions & 0 deletions packages/flutter/test/rendering/box_constraints_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -182,4 182,17 @@ void main() {
expect(constraints, const BoxConstraints(minWidth: 1, maxWidth: 2, minHeight: 3, maxHeight: 4));
});

test('BoxConstraints.constrainSizeAndAttemptToPreserveAspectRatio can handle empty size', () {
const BoxConstraints constraints = BoxConstraints(
minWidth: 10.0,
maxWidth: 20.0,
minHeight: 10.0,
maxHeight: 20.0,
);
const Size unconstrainedSize = Size(15.0, 0.0);
final Size constrainedSize = constraints.constrainSizeAndAttemptToPreserveAspectRatio(
unconstrainedSize,
);
expect(constrainedSize, const Size(15.0, 10.0));
});
}
32 changes: 32 additions & 0 deletions packages/flutter/test/widgets/fitted_box_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 605,38 @@ void main() {
await tester.tap(find.byType(FittedBox), warnIfMissed: false);
expect(tester.takeException(), isNull);
});

// Regression test for https://github.com/flutter/flutter/issues/135082
testWidgets('FittedBox with zero size child does not throw', (WidgetTester tester) async {
await tester.pumpWidget(
const Center(
child: SizedBox(
height: 200.0,
width: 200.0,
child: FittedBox(
fit: BoxFit.scaleDown,
child: SizedBox.shrink(),
),
),
),
);
expect(tester.takeException(), isNull);

await tester.pumpWidget(
Center(
child: ConstrainedBox(
constraints: const BoxConstraints(
maxWidth: 200.0,
maxHeight: 200.0,
),
child: const FittedBox(
child: SizedBox.shrink(),
),
),
),
);
expect(tester.takeException(), isNull);
});
}

List<Type> getLayers() {
Expand Down

0 comments on commit f194cd3

Please sign in to comment.