Skip to content

Commit 07928d5

Browse files
Fix Scaffold having status bar when primary is false (#175156)
When primary is false, `Scaffold` is not at the top of screen, so it should not have a status bar. fixes flutter/flutter#175062 ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
1 parent 18f1a2a commit 07928d5

2 files changed

Lines changed: 86 additions & 2 deletions

File tree

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1955,6 +1955,9 @@ class Scaffold extends StatefulWidget {
19551955
/// If true then the height of the [appBar] will be extended by the height
19561956
/// of the screen's status bar, i.e. the top padding for [MediaQuery].
19571957
///
1958+
/// If true, on iOS and macOS, tapping the status bar scrolls the app's
1959+
/// [PrimaryScrollController] to the top.
1960+
///
19581961
/// The default value of this property, like the default value of
19591962
/// [AppBar.primary], is true.
19601963
final bool primary;
@@ -2744,8 +2747,8 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin, Resto
27442747

27452748
// iOS FEATURES - status bar tap, back gesture
27462749

2747-
// On iOS, tapping the status bar scrolls the app's primary scrollable to the
2748-
// top. We implement this by looking up the primary scroll controller and
2750+
// On iOS and macOS, if `primary` is true, tapping the status bar scrolls the app's primary scrollable
2751+
// to the top. We implement this by looking up the primary scroll controller and
27492752
// scrolling it to the top when tapped.
27502753
void _handleStatusBarTap() {
27512754
final ScrollController? primaryScrollController = PrimaryScrollController.maybeOf(context);
@@ -3155,6 +3158,9 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin, Resto
31553158
switch (themeData.platform) {
31563159
case TargetPlatform.iOS:
31573160
case TargetPlatform.macOS:
3161+
if (!widget.primary) {
3162+
break;
3163+
}
31583164
_addIfNonNull(
31593165
children,
31603166
GestureDetector(

packages/flutter/test/material/scaffold_test.dart

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,84 @@ void main() {
614614
}),
615615
);
616616

617+
testWidgets(
618+
'No status bar when primary is false',
619+
(WidgetTester tester) async {
620+
await tester.pumpWidget(
621+
MaterialApp(
622+
theme: ThemeData(platform: debugDefaultTargetPlatformOverride),
623+
home: MediaQuery(
624+
data: const MediaQueryData(padding: EdgeInsets.only(top: 25.0)), // status bar
625+
child: Scaffold(
626+
primary: false,
627+
body: CustomScrollView(
628+
primary: true,
629+
slivers: <Widget>[
630+
const SliverAppBar(title: Text('Title')),
631+
SliverList.builder(
632+
itemCount: 20,
633+
itemBuilder: (BuildContext context, int index) {
634+
return SizedBox(height: 100.0, child: Text('$index'));
635+
},
636+
),
637+
],
638+
),
639+
),
640+
),
641+
),
642+
);
643+
final ScrollableState scrollable = tester.state(find.byType(Scrollable));
644+
scrollable.position.jumpTo(500.0);
645+
expect(scrollable.position.pixels, equals(500.0));
646+
await tester.tapAt(const Offset(100.0, 10.0));
647+
await tester.pumpAndSettle();
648+
expect(scrollable.position.pixels, equals(500.0));
649+
},
650+
variant: const TargetPlatformVariant(<TargetPlatform>{
651+
TargetPlatform.iOS,
652+
TargetPlatform.macOS,
653+
}),
654+
);
655+
656+
// Regression test for https://github.com/flutter/flutter/issues/175062
657+
testWidgets(
658+
'Top of Scaffold is not blocked when primary is false',
659+
(WidgetTester tester) async {
660+
bool receivedTap = false;
661+
await tester.pumpWidget(
662+
MaterialApp(
663+
theme: ThemeData(platform: debugDefaultTargetPlatformOverride),
664+
home: MediaQuery(
665+
data: const MediaQueryData(
666+
padding: EdgeInsets.only(top: kToolbarHeight), // status bar
667+
),
668+
child: Scaffold(
669+
appBar: AppBar(
670+
primary: false,
671+
title: GestureDetector(
672+
onTap: () {
673+
receivedTap = true;
674+
},
675+
child: const Text('Title'),
676+
),
677+
),
678+
primary: false,
679+
body: const Text('Scaffold'),
680+
),
681+
),
682+
),
683+
);
684+
await tester.pumpAndSettle();
685+
await tester.tap(find.text('Title'));
686+
await tester.pumpAndSettle();
687+
expect(receivedTap, true);
688+
},
689+
variant: const TargetPlatformVariant(<TargetPlatform>{
690+
TargetPlatform.iOS,
691+
TargetPlatform.macOS,
692+
}),
693+
);
694+
617695
testWidgets(
618696
'Tapping the status bar scrolls to top with ease out curve animation',
619697
(WidgetTester tester) async {

0 commit comments

Comments
 (0)