Skip to content

Commit 6388e3d

Browse files
authored
Floating SnackBar should always float above the bottom widgets (#136411)
Fixes #136162 This PR is to fix the floating `SnackBar` issue so that when the top of the bottom bar is higher than the top of the FAB, the snack bar will still float and not be clipped. | Before fix | After fix | |--------|--------| | ![Screenshot 2023-10-11 at 1 54 30 PM](https://github.com/flutter/flutter/assets/36861262/dbe02312-1a80-4532-9bad-a8f162a6a942) | ![Screenshot 2023-10-11 at 1 54 52 PM](https://github.com/flutter/flutter/assets/36861262/68211de0-f04f-4b1a-b554-baf6a8e2f947) |
1 parent d9c0d3a commit 6388e3d

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1165,7 +1165,11 @@ class _ScaffoldLayout extends MultiChildLayoutDelegate {
11651165
FloatingActionButtonLocation() => true,
11661166
};
11671167
if (floatingActionButtonRect.size != Size.zero && isSnackBarFloating && showAboveFab) {
1168-
snackBarYOffsetBase = floatingActionButtonRect.top;
1168+
if (bottomNavigationBarTop != null) {
1169+
snackBarYOffsetBase = math.min(bottomNavigationBarTop, floatingActionButtonRect.top);
1170+
} else {
1171+
snackBarYOffsetBase = floatingActionButtonRect.top;
1172+
}
11691173
} else {
11701174
// SnackBarBehavior.fixed applies a SafeArea automatically.
11711175
// SnackBarBehavior.floating does not since the positioning is affected

packages/flutter/test/material/snack_bar_test.dart

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2262,6 +2262,44 @@ void main() {
22622262
},
22632263
);
22642264

2265+
testWidgetsWithLeakTracking(
2266+
'${SnackBarBehavior.floating} should align SnackBar with the top of BottomNavigationBar '
2267+
'when Scaffold has both BottomNavigationBar and FloatingActionButton and '
2268+
'BottomNavigationBar.top is higher than FloatingActionButton.top',
2269+
(WidgetTester tester) async {
2270+
final UniqueKey boxKey = UniqueKey();
2271+
await tester.pumpWidget(
2272+
MaterialApp(
2273+
home: Scaffold(
2274+
body: Container(),
2275+
bottomNavigationBar: SizedBox(key: boxKey, width: 800, height: 200),
2276+
floatingActionButton: FloatingActionButton(onPressed: () {}),
2277+
floatingActionButtonLocation: FloatingActionButtonLocation.endContained,
2278+
),
2279+
),
2280+
);
2281+
2282+
final ScaffoldMessengerState scaffoldMessengerState = tester.state(find.byType(ScaffoldMessenger));
2283+
scaffoldMessengerState.showSnackBar(
2284+
const SnackBar(
2285+
content: Text('SnackBar text'),
2286+
behavior: SnackBarBehavior.floating,
2287+
),
2288+
);
2289+
2290+
await tester.pumpAndSettle(); // Have the SnackBar fully animate out.
2291+
2292+
final Offset snackBarBottomRight = tester.getBottomRight(find.byType(SnackBar));
2293+
final Offset fabTopRight = tester.getTopRight(find.byType(FloatingActionButton));
2294+
final Offset navBarTopRight = tester.getTopRight(find.byKey(boxKey));
2295+
2296+
// Test the top of the navigation bar is higher than the top of the floating action button.
2297+
expect(fabTopRight.dy, greaterThan(navBarTopRight.dy));
2298+
2299+
expect(snackBarBottomRight.dy, equals(navBarTopRight.dy));
2300+
},
2301+
);
2302+
22652303
Future<void> openFloatingSnackBar(WidgetTester tester) async {
22662304
final ScaffoldMessengerState scaffoldMessengerState = tester.state(find.byType(ScaffoldMessenger));
22672305
scaffoldMessengerState.showSnackBar(

0 commit comments

Comments
 (0)