Skip to content

Commit caadc25

Browse files
authored
Reland "fix a Scaffold extendBodyBehindAppBar update bug" (#106534)
1 parent 9e82386 commit caadc25

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

packages/flutter/lib/src/material/scaffold.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1958,6 +1958,8 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin, Resto
19581958
final GlobalKey<DrawerControllerState> _drawerKey = GlobalKey<DrawerControllerState>();
19591959
final GlobalKey<DrawerControllerState> _endDrawerKey = GlobalKey<DrawerControllerState>();
19601960

1961+
final GlobalKey _bodyKey = GlobalKey();
1962+
19611963
/// Whether this scaffold has a non-null [Scaffold.appBar].
19621964
bool get hasAppBar => widget.appBar != null;
19631965
/// Whether this scaffold has a non-null [Scaffold.drawer].
@@ -2653,7 +2655,7 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin, Resto
26532655
widget.body == null ? null : _BodyBuilder(
26542656
extendBody: widget.extendBody,
26552657
extendBodyBehindAppBar: widget.extendBodyBehindAppBar,
2656-
body: widget.body!,
2658+
body: KeyedSubtree(key: _bodyKey, child: widget.body!),
26572659
),
26582660
_ScaffoldSlot.body,
26592661
removeLeftPadding: false,

packages/flutter/test/material/scaffold_test.dart

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,39 @@ import 'package:flutter_test/flutter_test.dart';
1212
import '../widgets/semantics_tester.dart';
1313

1414
void main() {
15+
// Regression test for https://github.com/flutter/flutter/issues/103741
16+
testWidgets('extendBodyBehindAppBar change should not cause the body widget lose state', (WidgetTester tester) async {
17+
final ScrollController controller = ScrollController();
18+
Widget buildFrame({required bool extendBodyBehindAppBar}) {
19+
return MediaQuery(
20+
data: const MediaQueryData(),
21+
child: Directionality(
22+
textDirection: TextDirection.ltr,
23+
child: Scaffold(
24+
extendBodyBehindAppBar: extendBodyBehindAppBar,
25+
resizeToAvoidBottomInset: false,
26+
body: SingleChildScrollView(
27+
controller: controller,
28+
child: const FlutterLogo(
29+
size: 1107,
30+
),
31+
),
32+
),
33+
),
34+
);
35+
}
36+
37+
await tester.pumpWidget(buildFrame(extendBodyBehindAppBar: true));
38+
expect(controller.position.pixels, 0.0);
39+
40+
controller.jumpTo(100.0);
41+
await tester.pump();
42+
expect(controller.position.pixels, 100.0);
43+
44+
await tester.pumpWidget(buildFrame(extendBodyBehindAppBar: false));
45+
expect(controller.position.pixels, 100.0);
46+
});
47+
1548
testWidgets('Scaffold drawer callback test', (WidgetTester tester) async {
1649
bool isDrawerOpen = false;
1750
bool isEndDrawerOpen = false;
@@ -2402,6 +2435,7 @@ void main() {
24022435
' ancestor was:\n'
24032436
' Builder\n'
24042437
' The ancestors of this widget were:\n'
2438+
' KeyedSubtree-[GlobalKey#00000]\n'
24052439
' _BodyBuilder\n'
24062440
' MediaQuery\n'
24072441
' LayoutId-[<_ScaffoldSlot.body>]\n'

0 commit comments

Comments
 (0)