mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Fix floating SnackBar is not centered when RTL and Material 2 (#147861)
## Description This PR fixes floating `SnackBar` positioning when the text direction is RTL and the theme uses Material 2. In https://github.com/flutter/flutter/pull/140215, I fixed the `SnackBar` position for M3/RTL, but while doing so I broke the positioning for M2/RTL... Unfortunately, there was no existing test for this case. The solution is to not rely on `TextDirection` to compute the `SnackBar` position: the `SnackBar` is centered in both cases so the text direction has no impact on its positioning (it had some impact in the `SnackBar` content, but this is managed correctly). ## Related Issue Fixes https://github.com/flutter/flutter/issues/147838. ## Tests Adds 1 test.
This commit is contained in:
parent
a318c79979
commit
86a2613cee
@ -1217,13 +1217,7 @@ class _ScaffoldLayout extends MultiChildLayoutDelegate {
|
|||||||
: contentBottom;
|
: contentBottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
double xOffset = 0.0;
|
final double xOffset = hasCustomWidth ? (size.width - snackBarWidth!) / 2 : 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));
|
positionChild(_ScaffoldSlot.snackBar, Offset(xOffset, snackBarYOffsetBase - snackBarSize.height));
|
||||||
|
|
||||||
assert((){
|
assert((){
|
||||||
|
@ -819,7 +819,7 @@ class _SnackBarState extends State<SnackBar> {
|
|||||||
animation: heightM3Animation,
|
animation: heightM3Animation,
|
||||||
builder: (BuildContext context, Widget? child) {
|
builder: (BuildContext context, Widget? child) {
|
||||||
return Align(
|
return Align(
|
||||||
alignment: AlignmentDirectional.bottomStart,
|
alignment: Alignment.bottomLeft,
|
||||||
heightFactor: heightM3Animation.value,
|
heightFactor: heightM3Animation.value,
|
||||||
child: child,
|
child: child,
|
||||||
);
|
);
|
||||||
|
@ -2601,7 +2601,7 @@ void main() {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
testWidgets('Floating snackbar with custom width is centered when text direction is rtl', (WidgetTester tester) async {
|
testWidgets('Material3 - 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.
|
// Regression test for https://github.com/flutter/flutter/issues/140125.
|
||||||
const double customWidth = 400.0;
|
const double customWidth = 400.0;
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
@ -2631,7 +2631,51 @@ void main() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
await tester.tap(find.text('X'));
|
await tester.tap(find.text('X'));
|
||||||
await tester.pump(); // start animation
|
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('Material2 - Floating snackbar with custom width is centered when text direction is rtl', (WidgetTester tester) async {
|
||||||
|
// Regression test for https://github.com/flutter/flutter/issues/147838.
|
||||||
|
const double customWidth = 400.0;
|
||||||
|
await tester.pumpWidget(
|
||||||
|
MaterialApp(
|
||||||
|
theme: ThemeData(useMaterial3: false),
|
||||||
|
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));
|
await tester.pump(const Duration(milliseconds: 750));
|
||||||
|
|
||||||
final Finder materialFinder = find.descendant(
|
final Finder materialFinder = find.descendant(
|
||||||
|
Loading…
Reference in New Issue
Block a user