mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[Material] TabBarTheme text style parameters (#26533)
* Add labelStyle + unselectedLabelStyle to TabBarTheme
This commit is contained in:
parent
e4c8f1b993
commit
5e8e39723d
@ -29,7 +29,9 @@ class TabBarTheme extends Diagnosticable {
|
||||
this.indicator,
|
||||
this.indicatorSize,
|
||||
this.labelColor,
|
||||
this.labelStyle,
|
||||
this.unselectedLabelColor,
|
||||
this.unselectedLabelStyle,
|
||||
});
|
||||
|
||||
/// Default value for [TabBar.indicator].
|
||||
@ -41,22 +43,32 @@ class TabBarTheme extends Diagnosticable {
|
||||
/// Default value for [TabBar.labelColor].
|
||||
final Color labelColor;
|
||||
|
||||
/// Default value for [TabBar.labelStyle].
|
||||
final TextStyle labelStyle;
|
||||
|
||||
/// Default value for [TabBar.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
|
||||
/// new values.
|
||||
TabBarTheme copyWith({
|
||||
Decoration indicator,
|
||||
TabBarIndicatorSize indicatorSize,
|
||||
Color labelColor,
|
||||
TextStyle labelStyle,
|
||||
Color unselectedLabelColor,
|
||||
TextStyle unselectedLabelStyle,
|
||||
}) {
|
||||
return TabBarTheme(
|
||||
indicator: indicator ?? this.indicator,
|
||||
indicatorSize: indicatorSize ?? this.indicatorSize,
|
||||
labelColor: labelColor ?? this.labelColor,
|
||||
unselectedLabelColor: unselectedLabelColor ?? this.unselectedLabelColor
|
||||
indicator: indicator ?? this.indicator,
|
||||
indicatorSize: indicatorSize ?? this.indicatorSize,
|
||||
labelColor: labelColor ?? this.labelColor,
|
||||
labelStyle: labelStyle ?? this.labelStyle,
|
||||
unselectedLabelColor: unselectedLabelColor ?? this.unselectedLabelColor,
|
||||
unselectedLabelStyle: unselectedLabelStyle ?? this.unselectedLabelStyle,
|
||||
);
|
||||
}
|
||||
|
||||
@ -78,13 +90,22 @@ class TabBarTheme extends Diagnosticable {
|
||||
indicator: Decoration.lerp(a.indicator, b.indicator, t),
|
||||
indicatorSize: t < 0.5 ? a.indicatorSize : b.indicatorSize,
|
||||
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
|
||||
int get hashCode {
|
||||
return hashValues(indicator, indicatorSize, labelColor, unselectedLabelColor);
|
||||
return hashValues(
|
||||
indicator,
|
||||
indicatorSize,
|
||||
labelColor,
|
||||
labelStyle,
|
||||
unselectedLabelColor,
|
||||
unselectedLabelStyle,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@ -97,6 +118,8 @@ class TabBarTheme extends Diagnosticable {
|
||||
return typedOther.indicator == indicator
|
||||
&& typedOther.indicatorSize == indicatorSize
|
||||
&& typedOther.labelColor == labelColor
|
||||
&& typedOther.unselectedLabelColor == unselectedLabelColor;
|
||||
&& typedOther.labelStyle == labelStyle
|
||||
&& typedOther.unselectedLabelColor == unselectedLabelColor
|
||||
&& typedOther.unselectedLabelStyle == unselectedLabelStyle;
|
||||
}
|
||||
}
|
||||
|
||||
@ -154,20 +154,21 @@ class _TabStyle extends AnimatedWidget {
|
||||
final ThemeData themeData = Theme.of(context);
|
||||
final TabBarTheme tabBarTheme = TabBarTheme.of(context);
|
||||
|
||||
final TextStyle defaultStyle = labelStyle ?? themeData.primaryTextTheme.body2;
|
||||
final TextStyle defaultUnselectedStyle = unselectedLabelStyle ?? labelStyle ?? themeData.primaryTextTheme.body2;
|
||||
final TextStyle defaultStyle = labelStyle ?? tabBarTheme.labelStyle ?? themeData.primaryTextTheme.body2;
|
||||
final TextStyle defaultUnselectedStyle = unselectedLabelStyle
|
||||
?? tabBarTheme.unselectedLabelStyle
|
||||
?? labelStyle
|
||||
?? themeData.primaryTextTheme.body2;
|
||||
final Animation<double> animation = listenable;
|
||||
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;
|
||||
final Color unselectedColor =
|
||||
unselectedLabelColor
|
||||
?? tabBarTheme.unselectedLabelColor
|
||||
?? selectedColor.withAlpha(0xB2); // 70% alpha
|
||||
final Color selectedColor = labelColor
|
||||
?? tabBarTheme.labelColor
|
||||
?? themeData.primaryTextTheme.body2.color;
|
||||
final Color unselectedColor = unselectedLabelColor
|
||||
?? tabBarTheme.unselectedLabelColor
|
||||
?? selectedColor.withAlpha(0xB2); // 70% alpha
|
||||
final Color color = selected
|
||||
? Color.lerp(selectedColor, unselectedColor, animation.value)
|
||||
: Color.lerp(unselectedColor, selectedColor, animation.value);
|
||||
|
||||
@ -20,19 +20,18 @@ const List<Tab> _tabs = <Tab>[
|
||||
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) {
|
||||
return MaterialApp(
|
||||
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) {
|
||||
}
|
||||
|
||||
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 {
|
||||
const Color labelColor = Colors.black;
|
||||
const TabBarTheme tabBarTheme = TabBarTheme(labelColor: labelColor);
|
||||
@ -54,6 +66,51 @@ void main() {
|
||||
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 {
|
||||
const Color unselectedLabelColor = Colors.black;
|
||||
const TabBarTheme tabBarTheme = TabBarTheme(unselectedLabelColor: unselectedLabelColor);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user