From ca33836b4516792e97e8786a66032a991ffaaedb Mon Sep 17 00:00:00 2001 From: Renzo Olivares Date: Mon, 28 Aug 2023 15:27:39 -0700 Subject: [PATCH] Fix context menu button color on Android when textButtonTheme is set (#133271) Fixes #133027 When setting a `textButtonTheme` it should not override the native context menu colors. ```dart theme: ThemeData( textButtonTheme: const TextButtonThemeData( style: ButtonStyle( backgroundColor: MaterialStatePropertyAll( Color(0xff05164d)), // blue color ), ), ), ``` Before|After --|-- Screenshot 2023-08-24 at 1 17 25 PM|Screenshot 2023-08-24 at 1 15 35 PM --- .../text_selection_toolbar_text_button.dart | 7 ++ ...xt_selection_toolbar_text_button_test.dart | 67 +++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/packages/flutter/lib/src/material/text_selection_toolbar_text_button.dart b/packages/flutter/lib/src/material/text_selection_toolbar_text_button.dart index e4ac077c14..844da98ce0 100644 --- a/packages/flutter/lib/src/material/text_selection_toolbar_text_button.dart +++ b/packages/flutter/lib/src/material/text_selection_toolbar_text_button.dart @@ -135,6 +135,12 @@ class TextSelectionToolbarTextButton extends StatelessWidget { static const Color _defaultForegroundColorLight = Color(0xff000000); static const Color _defaultForegroundColorDark = Color(0xffffffff); + // The background color is hardcoded to transparent by default so the buttons + // are the color of the container behind them. For example TextSelectionToolbar + // hardcodes the color value, and TextSelectionToolbarTextButtons that are its + // children become that color. + static const Color _defaultBackgroundColorTransparent = Color(0x00000000); + static Color _getForegroundColor(ColorScheme colorScheme) { final bool isDefaultOnSurface = switch (colorScheme.brightness) { Brightness.light => identical(ThemeData().colorScheme.onSurface, colorScheme.onSurface), @@ -154,6 +160,7 @@ class TextSelectionToolbarTextButton extends StatelessWidget { final ColorScheme colorScheme = Theme.of(context).colorScheme; return TextButton( style: TextButton.styleFrom( + backgroundColor: _defaultBackgroundColorTransparent, foregroundColor: _getForegroundColor(colorScheme), shape: const RoundedRectangleBorder(), minimumSize: const Size(kMinInteractiveDimension, kMinInteractiveDimension), diff --git a/packages/flutter/test/material/text_selection_toolbar_text_button_test.dart b/packages/flutter/test/material/text_selection_toolbar_text_button_test.dart index f2f6cbd10c..24de64a800 100644 --- a/packages/flutter/test/material/text_selection_toolbar_text_button_test.dart +++ b/packages/flutter/test/material/text_selection_toolbar_text_button_test.dart @@ -123,5 +123,72 @@ void main() { customForegroundColor, ); }); + + testWidgetsWithLeakTracking('background color by default', (WidgetTester tester) async { + // Regression test for https://github.com/flutter/flutter/issues/133027 + await tester.pumpWidget( + MaterialApp( + theme: ThemeData( + colorScheme: colorScheme, + ), + home: Scaffold( + body: Center( + child: TextSelectionToolbarTextButton( + padding: TextSelectionToolbarTextButton.getPadding(0, 1), + child: const Text('button'), + ), + ), + ), + ), + ); + + expect(find.byType(TextButton), findsOneWidget); + + final TextButton textButton = tester.widget(find.byType(TextButton)); + // The background color is hardcoded to transparent by default so the buttons + // are the color of the container behind them. For example TextSelectionToolbar + // hardcodes the color value, and TextSelectionToolbarTextButton that are its + // children should be that color. + expect( + textButton.style!.backgroundColor!.resolve({}), + Colors.transparent, + ); + }); + + testWidgetsWithLeakTracking('textButtonTheme should not override default background color', (WidgetTester tester) async { + // Regression test for https://github.com/flutter/flutter/issues/133027 + await tester.pumpWidget( + MaterialApp( + theme: ThemeData( + colorScheme: colorScheme, + textButtonTheme: const TextButtonThemeData( + style: ButtonStyle( + backgroundColor: MaterialStatePropertyAll(Colors.blue), + ), + ), + ), + home: Scaffold( + body: Center( + child: TextSelectionToolbarTextButton( + padding: TextSelectionToolbarTextButton.getPadding(0, 1), + child: const Text('button'), + ), + ), + ), + ), + ); + + expect(find.byType(TextButton), findsOneWidget); + + final TextButton textButton = tester.widget(find.byType(TextButton)); + // The background color is hardcoded to transparent by default so the buttons + // are the color of the container behind them. For example TextSelectionToolbar + // hardcodes the color value, and TextSelectionToolbarTextButton that are its + // children should be that color. + expect( + textButton.style!.backgroundColor!.resolve({}), + Colors.transparent, + ); + }); } }