Unverified Commit 5e8e3972 authored by MH Johnson's avatar MH Johnson Committed by GitHub

[Material] TabBarTheme text style parameters (#26533)

* Add labelStyle + unselectedLabelStyle to TabBarTheme
parent e4c8f1b9
...@@ -29,7 +29,9 @@ class TabBarTheme extends Diagnosticable { ...@@ -29,7 +29,9 @@ class TabBarTheme extends Diagnosticable {
this.indicator, this.indicator,
this.indicatorSize, this.indicatorSize,
this.labelColor, this.labelColor,
this.labelStyle,
this.unselectedLabelColor, this.unselectedLabelColor,
this.unselectedLabelStyle,
}); });
/// Default value for [TabBar.indicator]. /// Default value for [TabBar.indicator].
...@@ -41,22 +43,32 @@ class TabBarTheme extends Diagnosticable { ...@@ -41,22 +43,32 @@ class TabBarTheme extends Diagnosticable {
/// Default value for [TabBar.labelColor]. /// Default value for [TabBar.labelColor].
final Color labelColor; final Color labelColor;
/// Default value for [TabBar.labelStyle].
final TextStyle labelStyle;
/// Default value for [TabBar.unselectedLabelColor]. /// Default value for [TabBar.unselectedLabelColor].
final Color unselectedLabelColor; final Color unselectedLabelColor;
/// Default value for [TabBar.unselectedLabelStyle].
final TextStyle unselectedLabelStyle;
/// Creates a copy of this object but with the given fields replaced with the /// Creates a copy of this object but with the given fields replaced with the
/// new values. /// new values.
TabBarTheme copyWith({ TabBarTheme copyWith({
Decoration indicator, Decoration indicator,
TabBarIndicatorSize indicatorSize, TabBarIndicatorSize indicatorSize,
Color labelColor, Color labelColor,
TextStyle labelStyle,
Color unselectedLabelColor, Color unselectedLabelColor,
TextStyle unselectedLabelStyle,
}) { }) {
return TabBarTheme( return TabBarTheme(
indicator: indicator ?? this.indicator, indicator: indicator ?? this.indicator,
indicatorSize: indicatorSize ?? this.indicatorSize, indicatorSize: indicatorSize ?? this.indicatorSize,
labelColor: labelColor ?? this.labelColor, labelColor: labelColor ?? this.labelColor,
unselectedLabelColor: unselectedLabelColor ?? this.unselectedLabelColor labelStyle: labelStyle ?? this.labelStyle,
unselectedLabelColor: unselectedLabelColor ?? this.unselectedLabelColor,
unselectedLabelStyle: unselectedLabelStyle ?? this.unselectedLabelStyle,
); );
} }
...@@ -78,13 +90,22 @@ class TabBarTheme extends Diagnosticable { ...@@ -78,13 +90,22 @@ class TabBarTheme extends Diagnosticable {
indicator: Decoration.lerp(a.indicator, b.indicator, t), indicator: Decoration.lerp(a.indicator, b.indicator, t),
indicatorSize: t < 0.5 ? a.indicatorSize : b.indicatorSize, indicatorSize: t < 0.5 ? a.indicatorSize : b.indicatorSize,
labelColor: Color.lerp(a.labelColor, b.labelColor, t), labelColor: Color.lerp(a.labelColor, b.labelColor, t),
unselectedLabelColor: Color.lerp(a.unselectedLabelColor, b.unselectedLabelColor, t) labelStyle: TextStyle.lerp(a.labelStyle, b.labelStyle, t),
unselectedLabelColor: Color.lerp(a.unselectedLabelColor, b.unselectedLabelColor, t),
unselectedLabelStyle: TextStyle.lerp(a.unselectedLabelStyle, b.unselectedLabelStyle, t),
); );
} }
@override @override
int get hashCode { int get hashCode {
return hashValues(indicator, indicatorSize, labelColor, unselectedLabelColor); return hashValues(
indicator,
indicatorSize,
labelColor,
labelStyle,
unselectedLabelColor,
unselectedLabelStyle,
);
} }
@override @override
...@@ -97,6 +118,8 @@ class TabBarTheme extends Diagnosticable { ...@@ -97,6 +118,8 @@ class TabBarTheme extends Diagnosticable {
return typedOther.indicator == indicator return typedOther.indicator == indicator
&& typedOther.indicatorSize == indicatorSize && typedOther.indicatorSize == indicatorSize
&& typedOther.labelColor == labelColor && typedOther.labelColor == labelColor
&& typedOther.unselectedLabelColor == unselectedLabelColor; && typedOther.labelStyle == labelStyle
&& typedOther.unselectedLabelColor == unselectedLabelColor
&& typedOther.unselectedLabelStyle == unselectedLabelStyle;
} }
} }
...@@ -154,20 +154,21 @@ class _TabStyle extends AnimatedWidget { ...@@ -154,20 +154,21 @@ class _TabStyle extends AnimatedWidget {
final ThemeData themeData = Theme.of(context); final ThemeData themeData = Theme.of(context);
final TabBarTheme tabBarTheme = TabBarTheme.of(context); final TabBarTheme tabBarTheme = TabBarTheme.of(context);
final TextStyle defaultStyle = labelStyle ?? themeData.primaryTextTheme.body2; final TextStyle defaultStyle = labelStyle ?? tabBarTheme.labelStyle ?? themeData.primaryTextTheme.body2;
final TextStyle defaultUnselectedStyle = unselectedLabelStyle ?? labelStyle ?? themeData.primaryTextTheme.body2; final TextStyle defaultUnselectedStyle = unselectedLabelStyle
?? tabBarTheme.unselectedLabelStyle
?? labelStyle
?? themeData.primaryTextTheme.body2;
final Animation<double> animation = listenable; final Animation<double> animation = listenable;
final TextStyle textStyle = selected final TextStyle textStyle = selected
? TextStyle.lerp(defaultStyle, defaultUnselectedStyle, animation.value) ? TextStyle.lerp(defaultStyle, defaultUnselectedStyle, animation.value)
: TextStyle.lerp(defaultUnselectedStyle, defaultStyle, animation.value); : TextStyle.lerp(defaultUnselectedStyle, defaultStyle, animation.value);
final Color selectedColor = final Color selectedColor = labelColor
labelColor ?? tabBarTheme.labelColor
?? tabBarTheme.labelColor ?? themeData.primaryTextTheme.body2.color;
?? themeData.primaryTextTheme.body2.color; final Color unselectedColor = unselectedLabelColor
final Color unselectedColor = ?? tabBarTheme.unselectedLabelColor
unselectedLabelColor ?? selectedColor.withAlpha(0xB2); // 70% alpha
?? tabBarTheme.unselectedLabelColor
?? selectedColor.withAlpha(0xB2); // 70% alpha
final Color color = selected final Color color = selected
? Color.lerp(selectedColor, unselectedColor, animation.value) ? Color.lerp(selectedColor, unselectedColor, animation.value)
: Color.lerp(unselectedColor, selectedColor, animation.value); : Color.lerp(unselectedColor, selectedColor, animation.value);
......
...@@ -20,19 +20,18 @@ const List<Tab> _tabs = <Tab>[ ...@@ -20,19 +20,18 @@ const List<Tab> _tabs = <Tab>[
Tab(text: _tab3Text, icon: Icon(Icons.looks_3)), Tab(text: _tab3Text, icon: Icon(Icons.looks_3)),
]; ];
Widget _buildTabBar({ List<Tab> tabs = _tabs }) {
final TabController _tabController = TabController(length: 3, vsync: const TestVSync());
return RepaintBoundary(
key: _painterKey,
child: TabBar(tabs: tabs, controller: _tabController),
);
}
Widget _withTheme(TabBarTheme theme) { Widget _withTheme(TabBarTheme theme) {
return MaterialApp( return MaterialApp(
theme: ThemeData(tabBarTheme: theme), theme: ThemeData(tabBarTheme: theme),
home: Scaffold(body: _buildTabBar()), home: Scaffold(
body: RepaintBoundary(
key: _painterKey,
child: TabBar(
tabs: _tabs,
controller: TabController(length: _tabs.length, vsync: const TestVSync()),
),
),
),
); );
} }
...@@ -42,6 +41,19 @@ RenderParagraph _iconRenderObject(WidgetTester tester, IconData icon) { ...@@ -42,6 +41,19 @@ RenderParagraph _iconRenderObject(WidgetTester tester, IconData icon) {
} }
void main() { void main() {
testWidgets('Tab bar defaults', (WidgetTester tester) async {
await tester.pumpWidget(_withTheme(null));
final RenderParagraph selectedRenderObject = tester.renderObject<RenderParagraph>(find.text(_tab1Text));
expect(selectedRenderObject.text.style.fontFamily, equals('Roboto'));
expect(selectedRenderObject.text.style.fontSize, equals(14.0));
expect(selectedRenderObject.text.style.color, equals(Colors.white));
final RenderParagraph unselectedRenderObject = tester.renderObject<RenderParagraph>(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 theme overrides label color (selected)', (WidgetTester tester) async { testWidgets('Tab bar theme overrides label color (selected)', (WidgetTester tester) async {
const Color labelColor = Colors.black; const Color labelColor = Colors.black;
const TabBarTheme tabBarTheme = TabBarTheme(labelColor: labelColor); const TabBarTheme tabBarTheme = TabBarTheme(labelColor: labelColor);
...@@ -54,6 +66,51 @@ void main() { ...@@ -54,6 +66,51 @@ void main() {
expect(iconRenderObject.text.style.color, equals(labelColor)); expect(iconRenderObject.text.style.color, equals(labelColor));
}); });
testWidgets('Tab bar theme overrides label styles', (WidgetTester tester) async {
const TextStyle labelStyle = TextStyle(fontFamily: 'foobar');
const TextStyle unselectedLabelStyle = TextStyle(fontFamily: 'baz');
const TabBarTheme tabBarTheme = TabBarTheme(
labelStyle: labelStyle,
unselectedLabelStyle: unselectedLabelStyle,
);
await tester.pumpWidget(_withTheme(tabBarTheme));
final RenderParagraph selectedRenderObject = tester.renderObject<RenderParagraph>(find.text(_tab1Text));
expect(selectedRenderObject.text.style.fontFamily, equals(labelStyle.fontFamily));
final RenderParagraph unselectedRenderObject = tester.renderObject<RenderParagraph>(find.text(_tab2Text));
expect(unselectedRenderObject.text.style.fontFamily, equals(unselectedLabelStyle.fontFamily));
});
testWidgets('Tab bar label styles override theme label styles', (WidgetTester tester) async {
const TextStyle labelStyle = TextStyle(fontFamily: '1');
const TextStyle unselectedLabelStyle = TextStyle(fontFamily: '2');
const TextStyle themeLabelStyle = TextStyle(fontFamily: '3');
const TextStyle themeUnselectedLabelStyle = TextStyle(fontFamily: '4');
const TabBarTheme tabBarTheme = TabBarTheme(
labelStyle: themeLabelStyle,
unselectedLabelStyle: themeUnselectedLabelStyle,
);
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(tabBarTheme: tabBarTheme),
home: Scaffold(body: TabBar(
tabs: _tabs,
controller: TabController(length: _tabs.length, vsync: const TestVSync()),
labelStyle: labelStyle,
unselectedLabelStyle: unselectedLabelStyle,
),
)
),
);
final RenderParagraph selectedRenderObject = tester.renderObject<RenderParagraph>(find.text(_tab1Text));
expect(selectedRenderObject.text.style.fontFamily, equals(labelStyle.fontFamily));
final RenderParagraph unselectedRenderObject = tester.renderObject<RenderParagraph>(find.text(_tab2Text));
expect(unselectedRenderObject.text.style.fontFamily, equals(unselectedLabelStyle.fontFamily));
});
testWidgets('Tab bar theme overrides label color (unselected)', (WidgetTester tester) async { testWidgets('Tab bar theme overrides label color (unselected)', (WidgetTester tester) async {
const Color unselectedLabelColor = Colors.black; const Color unselectedLabelColor = Colors.black;
const TabBarTheme tabBarTheme = TabBarTheme(unselectedLabelColor: unselectedLabelColor); const TabBarTheme tabBarTheme = TabBarTheme(unselectedLabelColor: unselectedLabelColor);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment