From 596d9b6c1a4eb955552837e74a1550fefc6918cb Mon Sep 17 00:00:00 2001 From: Bruno Leroux Date: Sat, 16 Dec 2023 20:23:11 +0100 Subject: [PATCH] Center Floating Snackbar with custom width when direction is RTL (#140215) ## Description This PR fixes the positionning of a floating snackbar when the text direction is RTL. ## Related Issue Fixes https://github.com/flutter/flutter/issues/140125. ## Tests Adds 1 test. --- .../flutter/lib/src/material/scaffold.dart | 8 +++- .../flutter/test/material/snack_bar_test.dart | 43 +++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/packages/flutter/lib/src/material/scaffold.dart b/packages/flutter/lib/src/material/scaffold.dart index 0a09824938809..c46860c7cd2bf 100644 --- a/packages/flutter/lib/src/material/scaffold.dart +++ b/packages/flutter/lib/src/material/scaffold.dart @@ -1183,7 +1183,13 @@ class _ScaffoldLayout extends MultiChildLayoutDelegate { : contentBottom; } - final double xOffset = hasCustomWidth ? (size.width - snackBarWidth!) / 2 : 0.0; + double xOffset = 0.0; + if (hasCustomWidth) { + xOffset = switch (textDirection) { + TextDirection.rtl => (snackBarWidth! - size.width) / 2, + TextDirection.ltr => (size.width - snackBarWidth!) / 2, + }; + } positionChild(_ScaffoldSlot.snackBar, Offset(xOffset, snackBarYOffsetBase - snackBarSize.height)); assert((){ diff --git a/packages/flutter/test/material/snack_bar_test.dart b/packages/flutter/test/material/snack_bar_test.dart index 1112e626b375a..64cd8d08f55d3 100644 --- a/packages/flutter/test/material/snack_bar_test.dart +++ b/packages/flutter/test/material/snack_bar_test.dart @@ -2604,6 +2604,49 @@ void main() { expect(snackBarTopRight.dx - actionTopRight.dx, 8.0 + 15.0); // button margin + horizontal scaffold outside margin }, ); + + testWidgets('Floating snackbar with custom width is centered when text direction is rtl', (WidgetTester tester) async { + // Regression test for https://github.com/flutter/flutter/issues/140125. + const double customWidth = 400.0; + await tester.pumpWidget( + MaterialApp( + home: Directionality( + textDirection: TextDirection.rtl, + child: Scaffold( + body: Builder( + builder: (BuildContext context) { + return GestureDetector( + onTap: () { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + behavior: SnackBarBehavior.floating, + width: customWidth, + content: Text('Feeling super snackish'), + ), + ); + }, + child: const Text('X'), + ); + }, + ), + ), + ), + ), + ); + + await tester.tap(find.text('X')); + await tester.pump(); // start animation + await tester.pump(const Duration(milliseconds: 750)); + + final Finder materialFinder = find.descendant( + of: find.byType(SnackBar), + matching: find.byType(Material), + ); + final Offset snackBarBottomLeft = tester.getBottomLeft(materialFinder); + final Offset snackBarBottomRight = tester.getBottomRight(materialFinder); + expect(snackBarBottomLeft.dx, (800 - customWidth) / 2); // Device width is 800. + expect(snackBarBottomRight.dx, (800 + customWidth) / 2); // Device width is 800. + }); }); testWidgets('SnackBars hero across transitions when using ScaffoldMessenger', (WidgetTester tester) async {