Unverified Commit 6388e3d7 authored by Qun Cheng's avatar Qun Cheng Committed by GitHub

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)
 |
parent d9c0d3ae
...@@ -1165,7 +1165,11 @@ class _ScaffoldLayout extends MultiChildLayoutDelegate { ...@@ -1165,7 +1165,11 @@ class _ScaffoldLayout extends MultiChildLayoutDelegate {
FloatingActionButtonLocation() => true, FloatingActionButtonLocation() => true,
}; };
if (floatingActionButtonRect.size != Size.zero && isSnackBarFloating && showAboveFab) { if (floatingActionButtonRect.size != Size.zero && isSnackBarFloating && showAboveFab) {
snackBarYOffsetBase = floatingActionButtonRect.top; if (bottomNavigationBarTop != null) {
snackBarYOffsetBase = math.min(bottomNavigationBarTop, floatingActionButtonRect.top);
} else {
snackBarYOffsetBase = floatingActionButtonRect.top;
}
} else { } else {
// SnackBarBehavior.fixed applies a SafeArea automatically. // SnackBarBehavior.fixed applies a SafeArea automatically.
// SnackBarBehavior.floating does not since the positioning is affected // SnackBarBehavior.floating does not since the positioning is affected
......
...@@ -2262,6 +2262,44 @@ void main() { ...@@ -2262,6 +2262,44 @@ void main() {
}, },
); );
testWidgetsWithLeakTracking(
'${SnackBarBehavior.floating} should align SnackBar with the top of BottomNavigationBar '
'when Scaffold has both BottomNavigationBar and FloatingActionButton and '
'BottomNavigationBar.top is higher than FloatingActionButton.top',
(WidgetTester tester) async {
final UniqueKey boxKey = UniqueKey();
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: Container(),
bottomNavigationBar: SizedBox(key: boxKey, width: 800, height: 200),
floatingActionButton: FloatingActionButton(onPressed: () {}),
floatingActionButtonLocation: FloatingActionButtonLocation.endContained,
),
),
);
final ScaffoldMessengerState scaffoldMessengerState = tester.state(find.byType(ScaffoldMessenger));
scaffoldMessengerState.showSnackBar(
const SnackBar(
content: Text('SnackBar text'),
behavior: SnackBarBehavior.floating,
),
);
await tester.pumpAndSettle(); // Have the SnackBar fully animate out.
final Offset snackBarBottomRight = tester.getBottomRight(find.byType(SnackBar));
final Offset fabTopRight = tester.getTopRight(find.byType(FloatingActionButton));
final Offset navBarTopRight = tester.getTopRight(find.byKey(boxKey));
// Test the top of the navigation bar is higher than the top of the floating action button.
expect(fabTopRight.dy, greaterThan(navBarTopRight.dy));
expect(snackBarBottomRight.dy, equals(navBarTopRight.dy));
},
);
Future<void> openFloatingSnackBar(WidgetTester tester) async { Future<void> openFloatingSnackBar(WidgetTester tester) async {
final ScaffoldMessengerState scaffoldMessengerState = tester.state(find.byType(ScaffoldMessenger)); final ScaffoldMessengerState scaffoldMessengerState = tester.state(find.byType(ScaffoldMessenger));
scaffoldMessengerState.showSnackBar( scaffoldMessengerState.showSnackBar(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment