Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit 0588b92

Browse files
authored
Removed "if" on resolving text color at "SnackBarAction" (#120050)
* Removed "if" on resolving text color at "SnackBarAction" Removed multiple "if" for "resolveForegroundColor" method at "SnackBarAction". At least one of the multiple "if" ("defaults.actionTextColor is MaterialStateColor") led to not applying a custom set color (e.g. MaterialColor "Colors.red") for the action text when using Material 3. The second "if" ("snackBarTheme.actionTextColor is MaterialStateColor") also makes no sense then as the set color of the Theme would lead to the same blocking behaviour of manual color assignment. The last remaining "if" ("widget.textColor is MaterialStateColor") will be unnecessary if the other "if" will be removed, as it will be resolved in the code right afterwards. The three "if" also seems to block the usage of the custom text color or the color at all if the widget is in the "MaterialState.disabled" state. * Adjusted recent modifications to SnackBarAction's text color resolution * Now the "widget.textColor" is checked if it is set. * If it is a MaterialStateColor, it will be used * Otherwise continue with normal resolution (It will be used in the resolution anyways because it's set) * Repeat same steps with "snackBarTheme.actionTextColor" if previous was not set * Repeat same steps with "defaults.actionTextColor" if previous was not set * Reverted the auto formatting changes * Added two test cases to "snack_bar_test" * Test for setting a MaterialColor to a SnackBarAction' label (M3) * Test for setting a MaterialStateColor to a SnackBarAction' label (M3) * Renamed test cases "Snackbar labels can be colored"
1 parent 75ca31b commit 0588b92

File tree

2 files changed

+134
-9
lines changed

2 files changed

+134
-9
lines changed

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

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -140,15 +140,20 @@ class _SnackBarActionState extends State<SnackBarAction> {
140140
final SnackBarThemeData snackBarTheme = Theme.of(context).snackBarTheme;
141141

142142
MaterialStateColor resolveForegroundColor() {
143-
if (widget.textColor is MaterialStateColor) {
144-
return widget.textColor! as MaterialStateColor;
145-
}
146-
if (snackBarTheme.actionTextColor is MaterialStateColor) {
147-
return snackBarTheme.actionTextColor! as MaterialStateColor;
148-
}
149-
if (defaults.actionTextColor is MaterialStateColor) {
150-
return defaults.actionTextColor! as MaterialStateColor;
143+
if (widget.textColor != null) {
144+
if (widget.textColor is MaterialStateColor) {
145+
return widget.textColor! as MaterialStateColor;
146+
}
147+
} else if (snackBarTheme.actionTextColor != null) {
148+
if (snackBarTheme.actionTextColor is MaterialStateColor) {
149+
return snackBarTheme.actionTextColor! as MaterialStateColor;
150+
}
151+
} else if (defaults.actionTextColor != null) {
152+
if (defaults.actionTextColor is MaterialStateColor) {
153+
return defaults.actionTextColor! as MaterialStateColor;
154+
}
151155
}
156+
152157
return MaterialStateColor.resolveWith((Set<MaterialState> states) {
153158
if (states.contains(MaterialState.disabled)) {
154159
return widget.disabledTextColor ??

packages/flutter/test/material/snack_bar_test.dart

Lines changed: 121 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -812,7 +812,7 @@ void main() {
812812
expect(snackBarBottomRight.dx, (800 + widgetWidth) / 2); // Device width is 800.
813813
});
814814

815-
testWidgets('Snackbar labels can be colored', (WidgetTester tester) async {
815+
testWidgets('Snackbar labels can be colored as MaterialColor (Material 2)', (WidgetTester tester) async {
816816
await tester.pumpWidget(
817817
MaterialApp(
818818
home: Scaffold(
@@ -856,6 +856,110 @@ void main() {
856856
}
857857
});
858858

859+
testWidgets('Snackbar labels can be colored as MaterialColor (Material 3)',
860+
(WidgetTester tester) async {
861+
const MaterialColor usedColor = Colors.teal;
862+
863+
await tester.pumpWidget(
864+
MaterialApp(
865+
theme: ThemeData(useMaterial3: true),
866+
home: Scaffold(
867+
body: Builder(
868+
builder: (BuildContext context) {
869+
return GestureDetector(
870+
onTap: () {
871+
ScaffoldMessenger.of(context).showSnackBar(
872+
SnackBar(
873+
content: const Text('I am a snack bar.'),
874+
duration: const Duration(seconds: 2),
875+
action: SnackBarAction(
876+
textColor: usedColor,
877+
label: 'ACTION',
878+
onPressed: () {},
879+
),
880+
),
881+
);
882+
},
883+
child: const Text('X'),
884+
);
885+
},
886+
),
887+
),
888+
),
889+
);
890+
891+
await tester.tap(find.text('X'));
892+
await tester.pump(); // start animation
893+
await tester.pump(const Duration(milliseconds: 750));
894+
895+
final Element actionTextButton =
896+
tester.element(find.widgetWithText(TextButton, 'ACTION'));
897+
final Widget textButton = actionTextButton.widget;
898+
if (textButton is TextButton) {
899+
final ButtonStyle buttonStyle = textButton.style!;
900+
if (buttonStyle.foregroundColor is MaterialStateColor) {
901+
// Same color when resolved
902+
expect(buttonStyle.foregroundColor!.resolve(<MaterialState>{}), usedColor);
903+
} else {
904+
expect(false, true);
905+
}
906+
} else {
907+
expect(false, true);
908+
}
909+
});
910+
911+
testWidgets('Snackbar labels can be colored as MaterialStateColor (Material 3)',
912+
(WidgetTester tester) async {
913+
const _TestMaterialStateColor usedColor = _TestMaterialStateColor();
914+
915+
await tester.pumpWidget(
916+
MaterialApp(
917+
theme: ThemeData(useMaterial3: true),
918+
home: Scaffold(
919+
body: Builder(
920+
builder: (BuildContext context) {
921+
return GestureDetector(
922+
onTap: () {
923+
ScaffoldMessenger.of(context).showSnackBar(
924+
SnackBar(
925+
content: const Text('I am a snack bar.'),
926+
duration: const Duration(seconds: 2),
927+
action: SnackBarAction(
928+
textColor: usedColor,
929+
label: 'ACTION',
930+
onPressed: () {},
931+
),
932+
),
933+
);
934+
},
935+
child: const Text('X'),
936+
);
937+
},
938+
),
939+
),
940+
),
941+
);
942+
943+
await tester.tap(find.text('X'));
944+
await tester.pump(); // start animation
945+
await tester.pump(const Duration(milliseconds: 750));
946+
947+
final Element actionTextButton =
948+
tester.element(find.widgetWithText(TextButton, 'ACTION'));
949+
final Widget textButton = actionTextButton.widget;
950+
if (textButton is TextButton) {
951+
final ButtonStyle buttonStyle = textButton.style!;
952+
if (buttonStyle.foregroundColor is MaterialStateColor) {
953+
// Exactly the same object
954+
expect(buttonStyle.foregroundColor, usedColor);
955+
} else {
956+
expect(false, true);
957+
}
958+
} else {
959+
expect(false, true);
960+
}
961+
});
962+
859963
testWidgets('SnackBar button text alignment', (WidgetTester tester) async {
860964
await tester.pumpWidget(MaterialApp(
861965
home: MediaQuery(
@@ -2588,3 +2692,19 @@ Map<DismissDirection, List<Offset>> _getDragGesturesOfDismissDirections(double s
25882692

25892693
return dragGestures;
25902694
}
2695+
2696+
class _TestMaterialStateColor extends MaterialStateColor {
2697+
const _TestMaterialStateColor() : super(_colorRed);
2698+
2699+
static const int _colorRed = 0xFFF44336;
2700+
static const int _colorBlue = 0xFF2196F3;
2701+
2702+
@override
2703+
Color resolve(Set<MaterialState> states) {
2704+
if (states.contains(MaterialState.pressed)) {
2705+
return const Color(_colorBlue);
2706+
}
2707+
2708+
return const Color(_colorRed);
2709+
}
2710+
}

0 commit comments

Comments
 (0)