diff --git a/packages/flutter/lib/src/material/tabs.dart b/packages/flutter/lib/src/material/tabs.dart index 005a6eab57e..e5fec0435b4 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 4444ac65644..1ea4d523bc0 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 7eb749376f4..501a318da1d 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 12b316cd2db..0c7996f40e6 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 2372a394ea9..db35550606b 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);