diff --git a/packages/flutter/lib/src/material/scaffold.dart b/packages/flutter/lib/src/material/scaffold.dart index 0cf8e3d323..844370f414 100644 --- a/packages/flutter/lib/src/material/scaffold.dart +++ b/packages/flutter/lib/src/material/scaffold.dart @@ -1087,17 +1087,21 @@ class _ScaffoldLayout extends MultiChildLayoutDelegate { if (hasChild(_ScaffoldSlot.body)) { double bodyMaxHeight = math.max(0.0, contentBottom - contentTop); - if (extendBody) { + // When extendBody is true, the body is visible underneath the bottom widgets. + // This does not apply when the area is obscured by the device keyboard. + if (extendBody && minInsets.bottom <= bottomWidgetsHeight) { bodyMaxHeight += bottomWidgetsHeight; bodyMaxHeight = clampDouble(bodyMaxHeight, 0.0, looseConstraints.maxHeight - contentTop); assert(bodyMaxHeight <= math.max(0.0, looseConstraints.maxHeight - contentTop)); + } else { + bottomWidgetsHeight = 0.0; } final BoxConstraints bodyConstraints = _BodyBoxConstraints( maxWidth: fullWidthConstraints.maxWidth, maxHeight: bodyMaxHeight, materialBannerHeight: materialBannerSize.height, - bottomWidgetsHeight: extendBody ? bottomWidgetsHeight : 0.0, + bottomWidgetsHeight: bottomWidgetsHeight, appBarHeight: appBarHeight, ); layoutChild(_ScaffoldSlot.body, bodyConstraints); @@ -3086,9 +3090,6 @@ class ScaffoldState extends State with TickerProviderStateMixin, Resto bottom: _resizeToAvoidBottomInset && MediaQuery.viewInsetsOf(context).bottom != 0.0 ? 0.0 : null, ); - // extendBody locked when keyboard is open - final bool extendBody = minInsets.bottom <= 0 && widget.extendBody; - return _ScaffoldScope( hasDrawer: hasDrawer, geometryNotifier: _geometryNotifier, @@ -3102,7 +3103,7 @@ class ScaffoldState extends State with TickerProviderStateMixin, Resto }, child: CustomMultiChildLayout( delegate: _ScaffoldLayout( - extendBody: extendBody, + extendBody: widget.extendBody, extendBodyBehindAppBar: widget.extendBodyBehindAppBar, minInsets: minInsets, minViewPadding: minViewPadding, diff --git a/packages/flutter/test/material/scaffold_test.dart b/packages/flutter/test/material/scaffold_test.dart index 1d30d63ad4..c0cf2cd5e1 100644 --- a/packages/flutter/test/material/scaffold_test.dart +++ b/packages/flutter/test/material/scaffold_test.dart @@ -3418,6 +3418,36 @@ void main() { )); expect(scaffoldMaterial.color, theme.colorScheme.surface); }); + + testWidgets('Body height remains Scaffold height when keyboard is smaller than bottomNavigationBar and extendBody is true', (WidgetTester tester) async { + final Key bodyKey = UniqueKey(); + Widget buildFrame({double keyboardHeight = 0}) { + return MaterialApp( + home: Builder( + builder: (BuildContext context) { + return MediaQuery( + data: MediaQuery.of(context).copyWith( + viewInsets: EdgeInsets.only(bottom: keyboardHeight), + ), + child: Scaffold( + extendBody: true, + body: SizedBox.expand(key: bodyKey), + bottomNavigationBar:const SizedBox(height: 100), + ), + ); + }, + ), + ); + } + await tester.pumpWidget(buildFrame()); + expect(tester.getSize(find.byKey(bodyKey)).height, 600); + + await tester.pumpWidget(buildFrame(keyboardHeight: 100)); + expect(tester.getSize(find.byKey(bodyKey)).height, 600); + + await tester.pumpWidget(buildFrame(keyboardHeight: 200)); + expect(tester.getSize(find.byKey(bodyKey)).height, 400); + }); } class _GeometryListener extends StatefulWidget {