From 47f56712cc0797a455eb4e70f48df267b6f1e450 Mon Sep 17 00:00:00 2001 From: Hans Muller Date: Tue, 12 Mar 2019 12:27:30 -0700 Subject: [PATCH] Ensure that animated pairs of Tabs TextStyles have matching inherited values (#29175) --- packages/flutter/lib/src/material/tabs.dart | 15 +++++++++++---- .../flutter/lib/src/painting/text_style.dart | 3 ++- .../test/material/tab_bar_theme_test.dart | 17 +++++++++++++++++ packages/flutter/test/material/theme_test.dart | 2 +- .../flutter/test/painting/text_style_test.dart | 6 ++++++ 5 files changed, 37 insertions(+), 6 deletions(-) diff --git a/packages/flutter/lib/src/material/tabs.dart b/packages/flutter/lib/src/material/tabs.dart index 005a6eab57..e5fec0435b 100644 --- a/packages/flutter/lib/src/material/tabs.dart +++ b/packages/flutter/lib/src/material/tabs.dart @@ -153,16 +153,23 @@ class _TabStyle extends AnimatedWidget { Widget build(BuildContext context) { final ThemeData themeData = Theme.of(context); final TabBarTheme tabBarTheme = TabBarTheme.of(context); + final Animation animation = listenable; - final TextStyle defaultStyle = labelStyle ?? tabBarTheme.labelStyle ?? themeData.primaryTextTheme.body2; - final TextStyle defaultUnselectedStyle = unselectedLabelStyle + // To enable TextStyle.lerp(style1, style2, value), both styles must have + // the same value of inherit. Force that to be inherit=true here. + final TextStyle defaultStyle = (labelStyle + ?? tabBarTheme.labelStyle + ?? themeData.primaryTextTheme.body2 + ).copyWith(inherit: true); + final TextStyle defaultUnselectedStyle = (unselectedLabelStyle ?? tabBarTheme.unselectedLabelStyle ?? labelStyle - ?? themeData.primaryTextTheme.body2; - final Animation animation = listenable; + ?? themeData.primaryTextTheme.body2 + ).copyWith(inherit: true); final TextStyle textStyle = selected ? TextStyle.lerp(defaultStyle, defaultUnselectedStyle, animation.value) : TextStyle.lerp(defaultUnselectedStyle, defaultStyle, animation.value); + final Color selectedColor = labelColor ?? tabBarTheme.labelColor ?? themeData.primaryTextTheme.body2.color; diff --git a/packages/flutter/lib/src/painting/text_style.dart b/packages/flutter/lib/src/painting/text_style.dart index 4444ac6564..1ea4d523bc 100644 --- a/packages/flutter/lib/src/painting/text_style.dart +++ b/packages/flutter/lib/src/painting/text_style.dart @@ -522,6 +522,7 @@ class TextStyle extends Diagnosticable { /// [background] specified it will be given preference over any /// backgroundColor parameter. TextStyle copyWith({ + bool inherit, Color color, Color backgroundColor, String fontFamily, @@ -551,7 +552,7 @@ class TextStyle extends Diagnosticable { return true; }()); return TextStyle( - inherit: inherit, + inherit: inherit ?? this.inherit, color: this.foreground == null && foreground == null ? color ?? this.color : null, backgroundColor: this.background == null && background == null ? backgroundColor ?? this.backgroundColor : null, fontFamily: fontFamily ?? this.fontFamily, diff --git a/packages/flutter/test/material/tab_bar_theme_test.dart b/packages/flutter/test/material/tab_bar_theme_test.dart index 7eb749376f..501a318da1 100644 --- a/packages/flutter/test/material/tab_bar_theme_test.dart +++ b/packages/flutter/test/material/tab_bar_theme_test.dart @@ -82,6 +82,23 @@ void main() { expect(unselectedRenderObject.text.style.fontFamily, equals(unselectedLabelStyle.fontFamily)); }); + testWidgets('Tab bar theme with just label style specified', (WidgetTester tester) async { + // Regression test for https://github.com/flutter/flutter/issues/28784 + const TextStyle labelStyle = TextStyle(fontFamily: 'foobar'); + const TabBarTheme tabBarTheme = TabBarTheme( + labelStyle: labelStyle, + ); + + await tester.pumpWidget(_withTheme(tabBarTheme)); + + final RenderParagraph selectedRenderObject = tester.renderObject(find.text(_tab1Text)); + expect(selectedRenderObject.text.style.fontFamily, equals(labelStyle.fontFamily)); + final RenderParagraph unselectedRenderObject = tester.renderObject(find.text(_tab2Text)); + expect(unselectedRenderObject.text.style.fontFamily, equals('Roboto')); + expect(unselectedRenderObject.text.style.fontSize, equals(14.0)); + expect(unselectedRenderObject.text.style.color, equals(Colors.white.withAlpha(0xB2))); + }); + testWidgets('Tab bar label styles override theme label styles', (WidgetTester tester) async { const TextStyle labelStyle = TextStyle(fontFamily: '1'); const TextStyle unselectedLabelStyle = TextStyle(fontFamily: '2'); diff --git a/packages/flutter/test/material/theme_test.dart b/packages/flutter/test/material/theme_test.dart index 12b316cd2d..0c7996f40e 100644 --- a/packages/flutter/test/material/theme_test.dart +++ b/packages/flutter/test/material/theme_test.dart @@ -731,7 +731,7 @@ class _TextStyleProxy implements TextStyle { } @override - TextStyle copyWith({ Color color, Color backgroundColor, String fontFamily, List fontFamilyFallback, double fontSize, FontWeight fontWeight, FontStyle fontStyle, double letterSpacing, double wordSpacing, TextBaseline textBaseline, double height, Locale locale, ui.Paint foreground, ui.Paint background, List shadows, TextDecoration decoration, Color decorationColor, TextDecorationStyle decorationStyle, String debugLabel }) { + TextStyle copyWith({ bool inherit, Color color, Color backgroundColor, String fontFamily, List fontFamilyFallback, double fontSize, FontWeight fontWeight, FontStyle fontStyle, double letterSpacing, double wordSpacing, TextBaseline textBaseline, double height, Locale locale, ui.Paint foreground, ui.Paint background, List shadows, TextDecoration decoration, Color decorationColor, TextDecorationStyle decorationStyle, String debugLabel }) { throw UnimplementedError(); } diff --git a/packages/flutter/test/painting/text_style_test.dart b/packages/flutter/test/painting/text_style_test.dart index 2372a394ea..db35550606 100644 --- a/packages/flutter/test/painting/text_style_test.dart +++ b/packages/flutter/test/painting/text_style_test.dart @@ -33,6 +33,12 @@ void main() { equals('TextStyle(inherit: true, size: 10.0, weight: 800, height: 123.0x)'), ); + // Check that the inherit flag can be set with copyWith(). + expect( + s1.copyWith(inherit: false).toString(), + equals('TextStyle(inherit: false, size: 10.0, weight: 800, height: 123.0x)'), + ); + final TextStyle s2 = s1.copyWith(color: const Color(0xFF00FF00), height: 100.0); expect(s1.fontFamily, isNull); expect(s1.fontSize, 10.0);