Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make FittedBox not throw when child has zero size. #150430

Merged
merged 11 commits into from
Jul 8, 2024
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