From 2b85eeed140cefa093f5461c9dd96f1247d8f236 Mon Sep 17 00:00:00 2001 From: xubaolin Date: Wed, 2 Dec 2020 01:48:10 +0800 Subject: [PATCH] Let SnackBar inherit themeData from its ancestor (#70080) --- .../flutter/lib/src/material/snack_bar.dart | 9 +- .../flutter/test/material/snack_bar_test.dart | 146 ++++++++++++++++++ .../material/text_selection_theme_test.dart | 4 +- 3 files changed, 151 insertions(+), 8 deletions(-) diff --git a/packages/flutter/lib/src/material/snack_bar.dart b/packages/flutter/lib/src/material/snack_bar.dart index 71a45b22318..29709a131a7 100644 --- a/packages/flutter/lib/src/material/snack_bar.dart +++ b/packages/flutter/lib/src/material/snack_bar.dart @@ -460,9 +460,7 @@ class _SnackBarState extends State { final Color themeBackgroundColor = isThemeDark ? colorScheme.onSurface : Color.alphaBlend(colorScheme.onSurface.withOpacity(0.80), colorScheme.surface); - final ThemeData inverseTheme = ThemeData( - brightness: brightness, - backgroundColor: themeBackgroundColor, + final ThemeData inverseTheme = theme.copyWith( colorScheme: ColorScheme( primary: colorScheme.onPrimary, primaryVariant: colorScheme.onPrimary, @@ -480,10 +478,9 @@ class _SnackBarState extends State { onError: colorScheme.error, brightness: brightness, ), - snackBarTheme: snackBarTheme, ); - final TextStyle? contentTextStyle = snackBarTheme.contentTextStyle ?? inverseTheme.textTheme.subtitle1; + final TextStyle? contentTextStyle = snackBarTheme.contentTextStyle ?? ThemeData(brightness: brightness).textTheme.subtitle1; final SnackBarBehavior snackBarBehavior = widget.behavior ?? snackBarTheme.behavior ?? SnackBarBehavior.fixed; final bool isFloatingSnackBar = snackBarBehavior == SnackBarBehavior.floating; final double horizontalPadding = isFloatingSnackBar ? 16.0 : 24.0; @@ -539,7 +536,7 @@ class _SnackBarState extends State { } final double elevation = widget.elevation ?? snackBarTheme.elevation ?? 6.0; - final Color backgroundColor = widget.backgroundColor ?? snackBarTheme.backgroundColor ?? inverseTheme.backgroundColor; + final Color backgroundColor = widget.backgroundColor ?? snackBarTheme.backgroundColor ?? inverseTheme.colorScheme.background; final ShapeBorder? shape = widget.shape ?? snackBarTheme.shape ?? (isFloatingSnackBar ? RoundedRectangleBorder(borderRadius: BorderRadius.circular(4.0)) : null); diff --git a/packages/flutter/test/material/snack_bar_test.dart b/packages/flutter/test/material/snack_bar_test.dart index 8337fb524ff..7fe96ccd28b 100644 --- a/packages/flutter/test/material/snack_bar_test.dart +++ b/packages/flutter/test/material/snack_bar_test.dart @@ -669,6 +669,152 @@ void main() { expect(renderModel.color, equals(darkTheme.colorScheme.onSurface)); }); + testWidgets('SnackBar should inherit theme data from its ancestor.', (WidgetTester tester) async { + final SliderThemeData sliderTheme = SliderThemeData.fromPrimaryColors( + primaryColor: Colors.black, + primaryColorDark: Colors.black, + primaryColorLight: Colors.black, + valueIndicatorTextStyle: const TextStyle(color: Colors.black), + ); + + final ChipThemeData chipTheme = ChipThemeData.fromDefaults( + primaryColor: Colors.black, + secondaryColor: Colors.white, + labelStyle: const TextStyle(color: Colors.black), + ); + + const PageTransitionsTheme pageTransitionTheme = PageTransitionsTheme( + builders: { + TargetPlatform.iOS: CupertinoPageTransitionsBuilder(), + TargetPlatform.macOS: CupertinoPageTransitionsBuilder(), + }, + ); + + final ThemeData theme = ThemeData.raw( + visualDensity: const VisualDensity(), + primaryColor: Colors.black, + primaryColorBrightness: Brightness.dark, + primaryColorLight: Colors.black, + primaryColorDark: Colors.black, + accentColor: Colors.black, + accentColorBrightness: Brightness.dark, + canvasColor: Colors.black, + shadowColor: Colors.black, + scaffoldBackgroundColor: Colors.black, + bottomAppBarColor: Colors.black, + cardColor: Colors.black, + dividerColor: Colors.black, + focusColor: Colors.black, + hoverColor: Colors.black, + highlightColor: Colors.black, + splashColor: Colors.black, + splashFactory: InkRipple.splashFactory, + selectedRowColor: Colors.black, + unselectedWidgetColor: Colors.black, + disabledColor: Colors.black, + buttonTheme: const ButtonThemeData(colorScheme: ColorScheme.dark()), + toggleButtonsTheme: const ToggleButtonsThemeData(textStyle: TextStyle(color: Colors.black)), + buttonColor: Colors.black, + secondaryHeaderColor: Colors.black, + textSelectionColor: Colors.black, + cursorColor: Colors.black, + textSelectionHandleColor: Colors.black, + backgroundColor: Colors.black, + dialogBackgroundColor: Colors.black, + indicatorColor: Colors.black, + hintColor: Colors.black, + errorColor: Colors.black, + toggleableActiveColor: Colors.black, + textTheme: ThemeData.dark().textTheme, + primaryTextTheme: ThemeData.dark().textTheme, + accentTextTheme: ThemeData.dark().textTheme, + inputDecorationTheme: ThemeData.dark().inputDecorationTheme.copyWith(border: const OutlineInputBorder()), + iconTheme: ThemeData.dark().iconTheme, + primaryIconTheme: ThemeData.dark().iconTheme, + accentIconTheme: ThemeData.dark().iconTheme, + sliderTheme: sliderTheme, + tabBarTheme: const TabBarTheme(labelColor: Colors.black), + tooltipTheme: const TooltipThemeData(height: 100), + cardTheme: const CardTheme(color: Colors.black), + chipTheme: chipTheme, + platform: TargetPlatform.iOS, + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + applyElevationOverlayColor: false, + pageTransitionsTheme: pageTransitionTheme, + appBarTheme: const AppBarTheme(color: Colors.black), + bottomAppBarTheme: const BottomAppBarTheme(color: Colors.black), + colorScheme: const ColorScheme.light(), + dialogTheme: const DialogTheme(backgroundColor: Colors.black), + floatingActionButtonTheme: const FloatingActionButtonThemeData(backgroundColor: Colors.black), + navigationRailTheme: const NavigationRailThemeData(backgroundColor: Colors.black), + typography: Typography.material2018(platform: TargetPlatform.android), + cupertinoOverrideTheme: null, + snackBarTheme: const SnackBarThemeData(backgroundColor: Colors.black), + bottomSheetTheme: const BottomSheetThemeData(backgroundColor: Colors.black), + popupMenuTheme: const PopupMenuThemeData(color: Colors.black), + bannerTheme: const MaterialBannerThemeData(backgroundColor: Colors.black), + dividerTheme: const DividerThemeData(color: Colors.black), + buttonBarTheme: const ButtonBarThemeData(alignment: MainAxisAlignment.start), + bottomNavigationBarTheme: const BottomNavigationBarThemeData(type: BottomNavigationBarType.fixed), + timePickerTheme: const TimePickerThemeData(backgroundColor: Colors.black), + textButtonTheme: TextButtonThemeData(style: TextButton.styleFrom(primary: Colors.red)), + elevatedButtonTheme: ElevatedButtonThemeData(style: ElevatedButton.styleFrom(primary: Colors.green)), + outlinedButtonTheme: OutlinedButtonThemeData(style: OutlinedButton.styleFrom(primary: Colors.blue)), + textSelectionTheme: const TextSelectionThemeData(cursorColor: Colors.black), + dataTableTheme: const DataTableThemeData(), + checkboxTheme: const CheckboxThemeData(), + radioTheme: const RadioThemeData(), + switchTheme: const SwitchThemeData(), + fixTextFieldOutlineLabel: false, + useTextSelectionTheme: false, + ); + + ThemeData? themeBeforeSnackBar; + ThemeData? themeAfterSnackBar; + await tester.pumpWidget( + MaterialApp( + theme: theme, + home: Scaffold( + body: Builder( + builder: (BuildContext context) { + themeBeforeSnackBar = Theme.of(context); + return GestureDetector( + onTap: () { + Scaffold.of(context).showSnackBar( + SnackBar( + content: Builder( + builder: (BuildContext context) { + themeAfterSnackBar = Theme.of(context); + return const Text('I am a snack bar.'); + }, + ), + duration: const Duration(seconds: 2), + action: SnackBarAction( + label: 'ACTION', + onPressed: () { }, + ), + ), + ); + }, + child: const Text('X'), + ); + }, + ), + ), + ), + ); + + await tester.tap(find.text('X')); + await tester.pump(); // start animation + await tester.pump(const Duration(milliseconds: 750)); + + final ThemeData comparedTheme = themeBeforeSnackBar!.copyWith( + colorScheme: themeAfterSnackBar!.colorScheme, + ); // Fields replaced by SnackBar. + + expect(comparedTheme, themeAfterSnackBar); + }); + testWidgets('Snackbar margin can be customized', (WidgetTester tester) async { const double padding = 20.0; await tester.pumpWidget( diff --git a/packages/flutter/test/material/text_selection_theme_test.dart b/packages/flutter/test/material/text_selection_theme_test.dart index 8f22cd444e6..be2a4541165 100644 --- a/packages/flutter/test/material/text_selection_theme_test.dart +++ b/packages/flutter/test/material/text_selection_theme_test.dart @@ -93,7 +93,7 @@ void main() { expect(handle, paints..path(color: defaultSelectionHandleColor)); }); - testWidgets('ThemeDate.textSelectionTheme will be used if provided', (WidgetTester tester) async { + testWidgets('ThemeData.textSelectionTheme will be used if provided', (WidgetTester tester) async { const TextSelectionThemeData textSelectionTheme = TextSelectionThemeData( cursorColor: Color(0xffaabbcc), selectionColor: Color(0x88888888), @@ -138,7 +138,7 @@ void main() { expect(handle, paints..path(color: textSelectionTheme.selectionHandleColor)); }); - testWidgets('TextSelectionTheme widget will override ThemeDate.textSelectionTheme', (WidgetTester tester) async { + testWidgets('TextSelectionTheme widget will override ThemeData.textSelectionTheme', (WidgetTester tester) async { const TextSelectionThemeData defaultTextSelectionTheme = TextSelectionThemeData( cursorColor: Color(0xffaabbcc), selectionColor: Color(0x88888888),