Normalize ThemeData.tabBarTheme (#156253)

Following https://github.com/flutter/flutter/pull/155476, this PR is to normalize `ThemeData.tabBarTheme`; change the `TabBarTheme tabBarTheme` property to `TabBarThemeData tabBarTheme` in `ThemeData`. In `ThemeData()` and `ThemeData.copyWith()`, the `tabBarTheme` parameter type is changed to `Object?` to accept both `TabBarTheme` and `TabBarThemeData` so that we won't cause immediate breaking change and make sure rolling is smooth. Once all component themes are normalized, these `Object?` types should be changed to `xxxThemeData`.

There's no way to create a dart fix because we can't add a "@deprecated" label for TabBarTheme; TabBarTheme is a new InheritedWidget subclass now.

Addresses the "theme normalization" sub project within https://github.com/flutter/flutter/issues/91772
This commit is contained in:
Qun Cheng 2024-10-08 12:52:38 -07:00 committed by GitHub
parent 12701dc619
commit e317860b35
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 84 additions and 65 deletions

View File

@ -245,9 +245,9 @@ class TabBarTheme extends InheritedTheme with Diagnosticable {
} }
/// Returns the closest [TabBarTheme] instance given the build context. /// Returns the closest [TabBarTheme] instance given the build context.
static TabBarTheme of(BuildContext context) { static TabBarThemeData of(BuildContext context) {
final TabBarTheme? tabBarTheme = context.dependOnInheritedWidgetOfExactType<TabBarTheme>(); final TabBarTheme? tabBarTheme = context.dependOnInheritedWidgetOfExactType<TabBarTheme>();
return tabBarTheme ?? Theme.of(context).tabBarTheme; return tabBarTheme?.data ?? Theme.of(context).tabBarTheme;
} }
/// Linearly interpolate between two tab bar themes. /// Linearly interpolate between two tab bar themes.

View File

@ -246,7 +246,7 @@ class _TabStyle extends AnimatedWidget {
MaterialStateColor _resolveWithLabelColor(BuildContext context) { MaterialStateColor _resolveWithLabelColor(BuildContext context) {
final ThemeData themeData = Theme.of(context); final ThemeData themeData = Theme.of(context);
final TabBarThemeData tabBarTheme = TabBarTheme.of(context).data; final TabBarThemeData tabBarTheme = TabBarTheme.of(context);
final Animation<double> animation = listenable as Animation<double>; final Animation<double> animation = listenable as Animation<double>;
// labelStyle.color (and tabBarTheme.labelStyle.color) is not considered // labelStyle.color (and tabBarTheme.labelStyle.color) is not considered
@ -285,7 +285,7 @@ class _TabStyle extends AnimatedWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final TabBarThemeData tabBarTheme = TabBarTheme.of(context).data; final TabBarThemeData tabBarTheme = TabBarTheme.of(context);
final Animation<double> animation = listenable as Animation<double>; final Animation<double> animation = listenable as Animation<double>;
final Set<MaterialState> states = isSelected final Set<MaterialState> states = isSelected
@ -1355,7 +1355,7 @@ class _TabBarState extends State<TabBar> {
Decoration _getIndicator(TabBarIndicatorSize indicatorSize) { Decoration _getIndicator(TabBarIndicatorSize indicatorSize) {
final ThemeData theme = Theme.of(context); final ThemeData theme = Theme.of(context);
final TabBarThemeData tabBarTheme = TabBarTheme.of(context).data; final TabBarThemeData tabBarTheme = TabBarTheme.of(context);
if (widget.indicator != null) { if (widget.indicator != null) {
return widget.indicator!; return widget.indicator!;
@ -1455,7 +1455,7 @@ class _TabBarState extends State<TabBar> {
void _initIndicatorPainter() { void _initIndicatorPainter() {
final ThemeData theme = Theme.of(context); final ThemeData theme = Theme.of(context);
final TabBarTheme tabBarTheme = TabBarTheme.of(context); final TabBarThemeData tabBarTheme = TabBarTheme.of(context);
final TabBarIndicatorSize indicatorSize = widget.indicatorSize final TabBarIndicatorSize indicatorSize = widget.indicatorSize
?? tabBarTheme.indicatorSize ?? tabBarTheme.indicatorSize
?? _defaults.indicatorSize!; ?? _defaults.indicatorSize!;
@ -1687,7 +1687,7 @@ class _TabBarState extends State<TabBar> {
assert(debugCheckHasMaterialLocalizations(context)); assert(debugCheckHasMaterialLocalizations(context));
assert(_debugScheduleCheckHasValidTabsCount()); assert(_debugScheduleCheckHasValidTabsCount());
final ThemeData theme = Theme.of(context); final ThemeData theme = Theme.of(context);
final TabBarThemeData tabBarTheme = TabBarTheme.of(context).data; final TabBarThemeData tabBarTheme = TabBarTheme.of(context);
final TabAlignment effectiveTabAlignment = widget.tabAlignment ?? tabBarTheme.tabAlignment ?? _defaults.tabAlignment!; final TabAlignment effectiveTabAlignment = widget.tabAlignment ?? tabBarTheme.tabAlignment ?? _defaults.tabAlignment!;
assert(_debugTabAlignmentIsValid(effectiveTabAlignment)); assert(_debugTabAlignmentIsValid(effectiveTabAlignment));

View File

@ -348,7 +348,8 @@ class ThemeData with Diagnosticable {
SliderThemeData? sliderTheme, SliderThemeData? sliderTheme,
SnackBarThemeData? snackBarTheme, SnackBarThemeData? snackBarTheme,
SwitchThemeData? switchTheme, SwitchThemeData? switchTheme,
TabBarTheme? tabBarTheme, // TODO(QuncCccccc): Change the parameter type to TabBarThemeData
Object? tabBarTheme,
TextButtonThemeData? textButtonTheme, TextButtonThemeData? textButtonTheme,
TextSelectionThemeData? textSelectionTheme, TextSelectionThemeData? textSelectionTheme,
TimePickerThemeData? timePickerTheme, TimePickerThemeData? timePickerTheme,
@ -541,7 +542,15 @@ class ThemeData with Diagnosticable {
sliderTheme ??= const SliderThemeData(); sliderTheme ??= const SliderThemeData();
snackBarTheme ??= const SnackBarThemeData(); snackBarTheme ??= const SnackBarThemeData();
switchTheme ??= const SwitchThemeData(); switchTheme ??= const SwitchThemeData();
tabBarTheme ??= const TabBarTheme(); // TODO(QuncCccccc): Clean this up once the type of `tabBarTheme` is changed to `TabBarThemeData`
if (tabBarTheme != null) {
if (tabBarTheme is TabBarTheme) {
tabBarTheme = tabBarTheme.data;
} else if (tabBarTheme is! TabBarThemeData) {
throw ArgumentError('tabBarTheme must be either a TabBarThemeData or a TabBarTheme');
}
}
tabBarTheme ??= const TabBarThemeData();
textButtonTheme ??= const TextButtonThemeData(); textButtonTheme ??= const TextButtonThemeData();
textSelectionTheme ??= const TextSelectionThemeData(); textSelectionTheme ??= const TextSelectionThemeData();
timePickerTheme ??= const TimePickerThemeData(); timePickerTheme ??= const TimePickerThemeData();
@ -634,7 +643,7 @@ class ThemeData with Diagnosticable {
sliderTheme: sliderTheme, sliderTheme: sliderTheme,
snackBarTheme: snackBarTheme, snackBarTheme: snackBarTheme,
switchTheme: switchTheme, switchTheme: switchTheme,
tabBarTheme: tabBarTheme, tabBarTheme: tabBarTheme as TabBarThemeData,
textButtonTheme: textButtonTheme, textButtonTheme: textButtonTheme,
textSelectionTheme: textSelectionTheme, textSelectionTheme: textSelectionTheme,
timePickerTheme: timePickerTheme, timePickerTheme: timePickerTheme,
@ -1387,7 +1396,7 @@ class ThemeData with Diagnosticable {
final SwitchThemeData switchTheme; final SwitchThemeData switchTheme;
/// A theme for customizing the size, shape, and color of the tab bar indicator. /// A theme for customizing the size, shape, and color of the tab bar indicator.
final TabBarTheme tabBarTheme; final TabBarThemeData tabBarTheme;
/// A theme for customizing the appearance and internal layout of /// A theme for customizing the appearance and internal layout of
/// [TextButton]s. /// [TextButton]s.
@ -1507,7 +1516,8 @@ class ThemeData with Diagnosticable {
SliderThemeData? sliderTheme, SliderThemeData? sliderTheme,
SnackBarThemeData? snackBarTheme, SnackBarThemeData? snackBarTheme,
SwitchThemeData? switchTheme, SwitchThemeData? switchTheme,
TabBarTheme? tabBarTheme, // TODO(QuncCccccc): Change the parameter type to TabBarThemeData
Object? tabBarTheme,
TextButtonThemeData? textButtonTheme, TextButtonThemeData? textButtonTheme,
TextSelectionThemeData? textSelectionTheme, TextSelectionThemeData? textSelectionTheme,
TimePickerThemeData? timePickerTheme, TimePickerThemeData? timePickerTheme,
@ -1547,6 +1557,15 @@ class ThemeData with Diagnosticable {
throw ArgumentError('dialogTheme must be either a DialogThemeData or a DialogTheme'); throw ArgumentError('dialogTheme must be either a DialogThemeData or a DialogTheme');
} }
} }
// TODO(QuncCccccc): Clean this up once the type of `tabBarTheme` is changed to `TabBarThemeData`
if (tabBarTheme != null) {
if (tabBarTheme is TabBarTheme) {
tabBarTheme = tabBarTheme.data;
} else if (tabBarTheme is! TabBarThemeData) {
throw ArgumentError('tabBarTheme must be either a TabBarThemeData or a TabBarTheme');
}
}
return ThemeData.raw( return ThemeData.raw(
// For the sanity of the reader, make sure these properties are in the same // For the sanity of the reader, make sure these properties are in the same
// order in every place that they are separated by section comments (e.g. // order in every place that they are separated by section comments (e.g.
@ -1634,7 +1653,7 @@ class ThemeData with Diagnosticable {
sliderTheme: sliderTheme ?? this.sliderTheme, sliderTheme: sliderTheme ?? this.sliderTheme,
snackBarTheme: snackBarTheme ?? this.snackBarTheme, snackBarTheme: snackBarTheme ?? this.snackBarTheme,
switchTheme: switchTheme ?? this.switchTheme, switchTheme: switchTheme ?? this.switchTheme,
tabBarTheme: tabBarTheme ?? this.tabBarTheme, tabBarTheme: tabBarTheme as TabBarThemeData? ?? this.tabBarTheme,
textButtonTheme: textButtonTheme ?? this.textButtonTheme, textButtonTheme: textButtonTheme ?? this.textButtonTheme,
textSelectionTheme: textSelectionTheme ?? this.textSelectionTheme, textSelectionTheme: textSelectionTheme ?? this.textSelectionTheme,
timePickerTheme: timePickerTheme ?? this.timePickerTheme, timePickerTheme: timePickerTheme ?? this.timePickerTheme,
@ -1827,7 +1846,7 @@ class ThemeData with Diagnosticable {
sliderTheme: SliderThemeData.lerp(a.sliderTheme, b.sliderTheme, t), sliderTheme: SliderThemeData.lerp(a.sliderTheme, b.sliderTheme, t),
snackBarTheme: SnackBarThemeData.lerp(a.snackBarTheme, b.snackBarTheme, t), snackBarTheme: SnackBarThemeData.lerp(a.snackBarTheme, b.snackBarTheme, t),
switchTheme: SwitchThemeData.lerp(a.switchTheme, b.switchTheme, t), switchTheme: SwitchThemeData.lerp(a.switchTheme, b.switchTheme, t),
tabBarTheme: TabBarTheme.lerp(a.tabBarTheme, b.tabBarTheme, t), tabBarTheme: TabBarThemeData.lerp(a.tabBarTheme, b.tabBarTheme, t),
textButtonTheme: TextButtonThemeData.lerp(a.textButtonTheme, b.textButtonTheme, t)!, textButtonTheme: TextButtonThemeData.lerp(a.textButtonTheme, b.textButtonTheme, t)!,
textSelectionTheme: TextSelectionThemeData.lerp(a.textSelectionTheme, b.textSelectionTheme, t)!, textSelectionTheme: TextSelectionThemeData.lerp(a.textSelectionTheme, b.textSelectionTheme, t)!,
timePickerTheme: TimePickerThemeData.lerp(a.timePickerTheme, b.timePickerTheme, t), timePickerTheme: TimePickerThemeData.lerp(a.timePickerTheme, b.timePickerTheme, t),
@ -2125,7 +2144,7 @@ class ThemeData with Diagnosticable {
properties.add(DiagnosticsProperty<SliderThemeData>('sliderTheme', sliderTheme, level: DiagnosticLevel.debug)); properties.add(DiagnosticsProperty<SliderThemeData>('sliderTheme', sliderTheme, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<SnackBarThemeData>('snackBarTheme', snackBarTheme, defaultValue: defaultData.snackBarTheme, level: DiagnosticLevel.debug)); properties.add(DiagnosticsProperty<SnackBarThemeData>('snackBarTheme', snackBarTheme, defaultValue: defaultData.snackBarTheme, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<SwitchThemeData>('switchTheme', switchTheme, defaultValue: defaultData.switchTheme, level: DiagnosticLevel.debug)); properties.add(DiagnosticsProperty<SwitchThemeData>('switchTheme', switchTheme, defaultValue: defaultData.switchTheme, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<TabBarTheme>('tabBarTheme', tabBarTheme, level: DiagnosticLevel.debug)); properties.add(DiagnosticsProperty<TabBarThemeData>('tabBarTheme', tabBarTheme, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<TextButtonThemeData>('textButtonTheme', textButtonTheme, defaultValue: defaultData.textButtonTheme, level: DiagnosticLevel.debug)); properties.add(DiagnosticsProperty<TextButtonThemeData>('textButtonTheme', textButtonTheme, defaultValue: defaultData.textButtonTheme, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<TextSelectionThemeData>('textSelectionTheme', textSelectionTheme, defaultValue: defaultData.textSelectionTheme, level: DiagnosticLevel.debug)); properties.add(DiagnosticsProperty<TextSelectionThemeData>('textSelectionTheme', textSelectionTheme, defaultValue: defaultData.textSelectionTheme, level: DiagnosticLevel.debug));
properties.add(DiagnosticsProperty<TimePickerThemeData>('timePickerTheme', timePickerTheme, defaultValue: defaultData.timePickerTheme, level: DiagnosticLevel.debug)); properties.add(DiagnosticsProperty<TimePickerThemeData>('timePickerTheme', timePickerTheme, defaultValue: defaultData.timePickerTheme, level: DiagnosticLevel.debug));

View File

@ -36,7 +36,7 @@ final List<SizedBox> _sizedTabs = <SizedBox>[
Widget buildTabBar({ Widget buildTabBar({
TabBarThemeData? localTabBarTheme, TabBarThemeData? localTabBarTheme,
TabBarTheme? tabBarTheme, TabBarThemeData? tabBarTheme,
bool secondaryTabBar = false, bool secondaryTabBar = false,
List<Widget> tabs = _tabs, List<Widget> tabs = _tabs,
bool isScrollable = false, bool isScrollable = false,
@ -316,7 +316,7 @@ void main() {
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 TabBarThemeData tabBarTheme = TabBarThemeData(labelColor: labelColor);
await tester.pumpWidget(buildTabBar(tabBarTheme: tabBarTheme)); await tester.pumpWidget(buildTabBar(tabBarTheme: tabBarTheme));
@ -337,7 +337,7 @@ void main() {
leftPadding, topPadding, rightPadding, bottomPadding, leftPadding, topPadding, rightPadding, bottomPadding,
); );
const TabBarTheme tabBarTheme = TabBarTheme(labelPadding: labelPadding); const TabBarThemeData tabBarTheme = TabBarThemeData(labelPadding: labelPadding);
await tester.pumpWidget(buildTabBar( await tester.pumpWidget(buildTabBar(
tabBarTheme: tabBarTheme, tabBarTheme: tabBarTheme,
@ -366,7 +366,7 @@ void main() {
testWidgets('Tab bar theme overrides label styles', (WidgetTester tester) async { testWidgets('Tab bar theme overrides label styles', (WidgetTester tester) async {
const TextStyle labelStyle = TextStyle(fontFamily: 'foobar'); const TextStyle labelStyle = TextStyle(fontFamily: 'foobar');
const TextStyle unselectedLabelStyle = TextStyle(fontFamily: 'baz'); const TextStyle unselectedLabelStyle = TextStyle(fontFamily: 'baz');
const TabBarTheme tabBarTheme = TabBarTheme( const TabBarThemeData tabBarTheme = TabBarThemeData(
labelStyle: labelStyle, labelStyle: labelStyle,
unselectedLabelStyle: unselectedLabelStyle, unselectedLabelStyle: unselectedLabelStyle,
); );
@ -382,7 +382,7 @@ void main() {
testWidgets('Tab bar theme with just label style specified', (WidgetTester tester) async { testWidgets('Tab bar theme with just label style specified', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/28784 // Regression test for https://github.com/flutter/flutter/issues/28784
const TextStyle labelStyle = TextStyle(fontFamily: 'foobar'); const TextStyle labelStyle = TextStyle(fontFamily: 'foobar');
const TabBarTheme tabBarTheme = TabBarTheme( const TabBarThemeData tabBarTheme = TabBarThemeData(
labelStyle: labelStyle, labelStyle: labelStyle,
); );
@ -401,7 +401,7 @@ void main() {
const TextStyle unselectedLabelStyle = TextStyle(fontFamily: '2'); const TextStyle unselectedLabelStyle = TextStyle(fontFamily: '2');
const TextStyle themeLabelStyle = TextStyle(fontFamily: '3'); const TextStyle themeLabelStyle = TextStyle(fontFamily: '3');
const TextStyle themeUnselectedLabelStyle = TextStyle(fontFamily: '4'); const TextStyle themeUnselectedLabelStyle = TextStyle(fontFamily: '4');
const TabBarTheme tabBarTheme = TabBarTheme( const TabBarThemeData tabBarTheme = TabBarThemeData(
labelStyle: themeLabelStyle, labelStyle: themeLabelStyle,
unselectedLabelStyle: themeUnselectedLabelStyle, unselectedLabelStyle: themeUnselectedLabelStyle,
); );
@ -448,7 +448,7 @@ void main() {
const double indicatorWeight = 2.0; // default value const double indicatorWeight = 2.0; // default value
const TabBarTheme tabBarTheme = TabBarTheme(labelPadding: themeLabelPadding); const TabBarThemeData tabBarTheme = TabBarThemeData(labelPadding: themeLabelPadding);
final TabController controller = TabController( final TabController controller = TabController(
length: _sizedTabs.length, length: _sizedTabs.length,
@ -509,7 +509,7 @@ void main() {
const double indicatorWeight = 2.0; // default value const double indicatorWeight = 2.0; // default value
const TabBarTheme tabBarTheme = TabBarTheme(labelPadding: themeLabelPadding); const TabBarThemeData tabBarTheme = TabBarThemeData(labelPadding: themeLabelPadding);
final TabController controller = TabController( final TabController controller = TabController(
length: _sizedTabs.length, length: _sizedTabs.length,
@ -554,7 +554,7 @@ void main() {
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 TabBarThemeData tabBarTheme = TabBarThemeData(unselectedLabelColor: unselectedLabelColor);
await tester.pumpWidget(buildTabBar(tabBarTheme: tabBarTheme)); await tester.pumpWidget(buildTabBar(tabBarTheme: tabBarTheme));
@ -583,7 +583,7 @@ void main() {
}); });
testWidgets('Tab bar theme overrides tab indicator size (tab)', (WidgetTester tester) async { testWidgets('Tab bar theme overrides tab indicator size (tab)', (WidgetTester tester) async {
const TabBarTheme tabBarTheme = TabBarTheme(indicatorSize: TabBarIndicatorSize.tab); const TabBarThemeData tabBarTheme = TabBarThemeData(indicatorSize: TabBarIndicatorSize.tab);
await tester.pumpWidget(buildTabBar(tabBarTheme: tabBarTheme)); await tester.pumpWidget(buildTabBar(tabBarTheme: tabBarTheme));
@ -594,7 +594,7 @@ void main() {
}); });
testWidgets('Tab bar theme overrides tab indicator size (label)', (WidgetTester tester) async { testWidgets('Tab bar theme overrides tab indicator size (label)', (WidgetTester tester) async {
const TabBarTheme tabBarTheme = TabBarTheme(indicatorSize: TabBarIndicatorSize.label); const TabBarThemeData tabBarTheme = TabBarThemeData(indicatorSize: TabBarIndicatorSize.label);
await tester.pumpWidget(buildTabBar(tabBarTheme: tabBarTheme)); await tester.pumpWidget(buildTabBar(tabBarTheme: tabBarTheme));
@ -605,7 +605,7 @@ void main() {
}); });
testWidgets('Tab bar theme overrides tab mouse cursor', (WidgetTester tester) async { testWidgets('Tab bar theme overrides tab mouse cursor', (WidgetTester tester) async {
const TabBarTheme tabBarTheme = TabBarTheme(mouseCursor: MaterialStateMouseCursor.textable); const TabBarThemeData tabBarTheme = TabBarThemeData(mouseCursor: MaterialStateMouseCursor.textable);
await tester.pumpWidget(buildTabBar(tabBarTheme: tabBarTheme)); await tester.pumpWidget(buildTabBar(tabBarTheme: tabBarTheme));
@ -620,7 +620,7 @@ void main() {
}); });
testWidgets('Tab bar theme - custom tab indicator', (WidgetTester tester) async { testWidgets('Tab bar theme - custom tab indicator', (WidgetTester tester) async {
final TabBarTheme tabBarTheme = TabBarTheme( final TabBarThemeData tabBarTheme = TabBarThemeData(
indicator: BoxDecoration( indicator: BoxDecoration(
border: Border.all(), border: Border.all(),
), ),
@ -635,7 +635,7 @@ void main() {
}); });
testWidgets('Tab bar theme - beveled rect indicator', (WidgetTester tester) async { testWidgets('Tab bar theme - beveled rect indicator', (WidgetTester tester) async {
const TabBarTheme tabBarTheme = TabBarTheme( const TabBarThemeData tabBarTheme = TabBarThemeData(
indicator: ShapeDecoration( indicator: ShapeDecoration(
shape: BeveledRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(20.0))), shape: BeveledRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(20.0))),
color: Colors.black, color: Colors.black,
@ -651,7 +651,7 @@ void main() {
}); });
testWidgets('TabAlignment.fill from TabBarTheme only supports non-scrollable tab bar', (WidgetTester tester) async { testWidgets('TabAlignment.fill from TabBarTheme only supports non-scrollable tab bar', (WidgetTester tester) async {
const TabBarTheme tabBarTheme = TabBarTheme(tabAlignment: TabAlignment.fill); const TabBarThemeData tabBarTheme = TabBarThemeData(tabAlignment: TabAlignment.fill);
// Test TabAlignment.fill from TabBarTheme with non-scrollable tab bar. // Test TabAlignment.fill from TabBarTheme with non-scrollable tab bar.
await tester.pumpWidget(buildTabBar(tabBarTheme: tabBarTheme)); await tester.pumpWidget(buildTabBar(tabBarTheme: tabBarTheme));
@ -667,7 +667,7 @@ void main() {
testWidgets( testWidgets(
'TabAlignment.start & TabAlignment.startOffset from TabBarTheme only supports scrollable tab bar', 'TabAlignment.start & TabAlignment.startOffset from TabBarTheme only supports scrollable tab bar',
(WidgetTester tester) async { (WidgetTester tester) async {
TabBarTheme tabBarTheme = const TabBarTheme(tabAlignment: TabAlignment.start); TabBarThemeData tabBarTheme = const TabBarThemeData(tabAlignment: TabAlignment.start);
// Test TabAlignment.start from TabBarTheme with scrollable tab bar. // Test TabAlignment.start from TabBarTheme with scrollable tab bar.
await tester.pumpWidget(buildTabBar(tabBarTheme: tabBarTheme, isScrollable: true)); await tester.pumpWidget(buildTabBar(tabBarTheme: tabBarTheme, isScrollable: true));
@ -679,7 +679,7 @@ void main() {
expect(tester.takeException(), isAssertionError); expect(tester.takeException(), isAssertionError);
tabBarTheme = const TabBarTheme(tabAlignment: TabAlignment.startOffset); tabBarTheme = const TabBarThemeData(tabAlignment: TabAlignment.startOffset);
// Test TabAlignment.startOffset from TabBarTheme with scrollable tab bar. // Test TabAlignment.startOffset from TabBarTheme with scrollable tab bar.
await tester.pumpWidget(buildTabBar(tabBarTheme: tabBarTheme, isScrollable: true)); await tester.pumpWidget(buildTabBar(tabBarTheme: tabBarTheme, isScrollable: true));
@ -694,7 +694,7 @@ void main() {
testWidgets('TabBarTheme.indicatorSize provides correct tab indicator (primary)', (WidgetTester tester) async { testWidgets('TabBarTheme.indicatorSize provides correct tab indicator (primary)', (WidgetTester tester) async {
final ThemeData theme = ThemeData( final ThemeData theme = ThemeData(
tabBarTheme: const TabBarTheme(indicatorSize: TabBarIndicatorSize.tab), tabBarTheme: const TabBarThemeData(indicatorSize: TabBarIndicatorSize.tab),
useMaterial3: true, useMaterial3: true,
); );
final List<Widget> tabs = List<Widget>.generate(4, (int index) { final List<Widget> tabs = List<Widget>.generate(4, (int index) {
@ -750,7 +750,7 @@ void main() {
testWidgets('TabBarTheme.indicatorSize provides correct tab indicator (secondary)', (WidgetTester tester) async { testWidgets('TabBarTheme.indicatorSize provides correct tab indicator (secondary)', (WidgetTester tester) async {
final ThemeData theme = ThemeData( final ThemeData theme = ThemeData(
tabBarTheme: const TabBarTheme(indicatorSize: TabBarIndicatorSize.label), tabBarTheme: const TabBarThemeData(indicatorSize: TabBarIndicatorSize.label),
useMaterial3: true, useMaterial3: true,
); );
final List<Widget> tabs = List<Widget>.generate(4, (int index) { final List<Widget> tabs = List<Widget>.generate(4, (int index) {
@ -815,7 +815,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
theme: ThemeData( theme: ThemeData(
tabBarTheme: const TabBarTheme( tabBarTheme: const TabBarThemeData(
dividerColor: dividerColor, dividerColor: dividerColor,
dividerHeight: dividerHeight, dividerHeight: dividerHeight,
), ),
@ -855,7 +855,7 @@ void main() {
MaterialApp( MaterialApp(
theme: ThemeData( theme: ThemeData(
useMaterial3: true, useMaterial3: true,
tabBarTheme: const TabBarTheme( tabBarTheme: const TabBarThemeData(
dividerColor: Colors.pink, dividerColor: Colors.pink,
dividerHeight: 5.0, dividerHeight: 5.0,
), ),
@ -893,7 +893,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
theme: ThemeData( theme: ThemeData(
tabBarTheme: const TabBarTheme(tabAlignment: TabAlignment.center), tabBarTheme: const TabBarThemeData(tabAlignment: TabAlignment.center),
useMaterial3: true, useMaterial3: true,
), ),
home: Scaffold( home: Scaffold(
@ -929,7 +929,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
theme: ThemeData( theme: ThemeData(
tabBarTheme: const TabBarTheme(tabAlignment: TabAlignment.start), tabBarTheme: const TabBarThemeData(tabAlignment: TabAlignment.start),
useMaterial3: true, useMaterial3: true,
), ),
home: Scaffold( home: Scaffold(
@ -968,7 +968,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
theme: ThemeData( theme: ThemeData(
tabBarTheme: const TabBarTheme(tabAlignment: TabAlignment.fill), tabBarTheme: const TabBarThemeData(tabAlignment: TabAlignment.fill),
useMaterial3: true, useMaterial3: true,
), ),
home: Scaffold( home: Scaffold(
@ -1005,7 +1005,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
theme: ThemeData( theme: ThemeData(
tabBarTheme: const TabBarTheme(tabAlignment: TabAlignment.center), tabBarTheme: const TabBarThemeData(tabAlignment: TabAlignment.center),
useMaterial3: true, useMaterial3: true,
), ),
home: Scaffold( home: Scaffold(
@ -1045,7 +1045,7 @@ void main() {
color: Color(0x950000ff), color: Color(0x950000ff),
fontStyle: FontStyle.italic, fontStyle: FontStyle.italic,
); );
const TabBarTheme tabBarTheme = TabBarTheme( const TabBarThemeData tabBarTheme = TabBarThemeData(
labelStyle: labelStyle, labelStyle: labelStyle,
unselectedLabelStyle: unselectedLabelStyle, unselectedLabelStyle: unselectedLabelStyle,
); );
@ -1082,7 +1082,7 @@ void main() {
color: Color(0x950000ff), color: Color(0x950000ff),
fontStyle: FontStyle.italic, fontStyle: FontStyle.italic,
); );
TabBarTheme tabBarTheme = const TabBarTheme( TabBarThemeData tabBarTheme = const TabBarThemeData(
labelStyle: labelStyle, labelStyle: labelStyle,
unselectedLabelStyle: unselectedLabelStyle, unselectedLabelStyle: unselectedLabelStyle,
); );
@ -1109,7 +1109,7 @@ void main() {
expect(unselectedTextStyle.fontStyle, unselectedLabelStyle.fontStyle); expect(unselectedTextStyle.fontStyle, unselectedLabelStyle.fontStyle);
// Update the TabBarTheme with labelColor & unselectedLabelColor. // Update the TabBarTheme with labelColor & unselectedLabelColor.
tabBarTheme = const TabBarTheme( tabBarTheme = const TabBarThemeData(
labelColor: labelColor, labelColor: labelColor,
unselectedLabelColor: unselectedLabelColor, unselectedLabelColor: unselectedLabelColor,
labelStyle: labelStyle, labelStyle: labelStyle,
@ -1147,7 +1147,7 @@ void main() {
fontStyle: FontStyle.italic, fontStyle: FontStyle.italic,
); );
Widget buildTabBar({TabBarTheme? tabBarTheme}) { Widget buildTabBar({TabBarThemeData? tabBarTheme}) {
return MaterialApp( return MaterialApp(
theme: ThemeData(tabBarTheme: tabBarTheme), theme: ThemeData(tabBarTheme: tabBarTheme),
home: const Material( home: const Material(
@ -1186,7 +1186,7 @@ void main() {
expect(unselectedTextStyle.fontStyle, unselectedLabelStyle.fontStyle); expect(unselectedTextStyle.fontStyle, unselectedLabelStyle.fontStyle);
// Add TabBarTheme with labelColor & unselectedLabelColor. // Add TabBarTheme with labelColor & unselectedLabelColor.
await tester.pumpWidget(buildTabBar(tabBarTheme: const TabBarTheme( await tester.pumpWidget(buildTabBar(tabBarTheme: const TabBarThemeData(
labelColor: labelColor, labelColor: labelColor,
unselectedLabelColor: unselectedLabelColor, unselectedLabelColor: unselectedLabelColor,
))); )));
@ -1303,7 +1303,7 @@ void main() {
testWidgets('TabBarTheme.indicatorSize provides correct tab indicator (primary)', (WidgetTester tester) async { testWidgets('TabBarTheme.indicatorSize provides correct tab indicator (primary)', (WidgetTester tester) async {
final ThemeData theme = ThemeData( final ThemeData theme = ThemeData(
tabBarTheme: const TabBarTheme(indicatorSize: TabBarIndicatorSize.tab), tabBarTheme: const TabBarThemeData(indicatorSize: TabBarIndicatorSize.tab),
useMaterial3: false, useMaterial3: false,
); );
final List<Widget> tabs = List<Widget>.generate(4, (int index) { final List<Widget> tabs = List<Widget>.generate(4, (int index) {
@ -1354,7 +1354,7 @@ void main() {
testWidgets('TabBarTheme.indicatorSize provides correct tab indicator (secondary)', (WidgetTester tester) async { testWidgets('TabBarTheme.indicatorSize provides correct tab indicator (secondary)', (WidgetTester tester) async {
final ThemeData theme = ThemeData( final ThemeData theme = ThemeData(
tabBarTheme: const TabBarTheme(indicatorSize: TabBarIndicatorSize.label), tabBarTheme: const TabBarThemeData(indicatorSize: TabBarIndicatorSize.label),
useMaterial3: false, useMaterial3: false,
); );
final List<Widget> tabs = List<Widget>.generate(4, (int index) { final List<Widget> tabs = List<Widget>.generate(4, (int index) {
@ -1412,7 +1412,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
theme: ThemeData( theme: ThemeData(
tabBarTheme: const TabBarTheme(tabAlignment: TabAlignment.center), tabBarTheme: const TabBarThemeData(tabAlignment: TabAlignment.center),
useMaterial3: false, useMaterial3: false,
), ),
home: Scaffold( home: Scaffold(
@ -1449,7 +1449,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
theme: ThemeData( theme: ThemeData(
tabBarTheme: const TabBarTheme(tabAlignment: TabAlignment.fill), tabBarTheme: const TabBarThemeData(tabAlignment: TabAlignment.fill),
useMaterial3: false, useMaterial3: false,
), ),
home: Scaffold( home: Scaffold(
@ -1512,7 +1512,7 @@ void main() {
await tester.pumpWidget(buildTabBar(theme: ThemeData( await tester.pumpWidget(buildTabBar(theme: ThemeData(
useMaterial3: true, useMaterial3: true,
tabBarTheme: const TabBarTheme(indicatorColor: tabBarThemeIndicatorColor) tabBarTheme: const TabBarThemeData(indicatorColor: tabBarThemeIndicatorColor)
))); )));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
@ -1538,7 +1538,7 @@ void main() {
return MaterialApp( return MaterialApp(
theme: ThemeData( theme: ThemeData(
indicatorColor: themeIndicatorColor, indicatorColor: themeIndicatorColor,
tabBarTheme: TabBarTheme(indicatorColor: tabBarThemeIndicatorColor), tabBarTheme: TabBarThemeData(indicatorColor: tabBarThemeIndicatorColor),
useMaterial3: false, useMaterial3: false,
), ),
home: Material( home: Material(
@ -1575,7 +1575,7 @@ void main() {
return unselectedColor; return unselectedColor;
}); });
final TabBarTheme tabBarTheme = TabBarTheme(labelColor: labelColor); final TabBarThemeData tabBarTheme = TabBarThemeData(labelColor: labelColor);
// Test labelColor correctly resolves material states. // Test labelColor correctly resolves material states.
await tester.pumpWidget(buildTabBar(tabBarTheme: tabBarTheme)); await tester.pumpWidget(buildTabBar(tabBarTheme: tabBarTheme));
@ -1604,7 +1604,7 @@ void main() {
const Color selectedColor = Color(0xff00ffff); const Color selectedColor = Color(0xff00ffff);
const Color unselectedColor = Color(0xffff12ff); const Color unselectedColor = Color(0xffff12ff);
TabBarTheme tabBarTheme = TabBarTheme(labelColor: labelColor); TabBarThemeData tabBarTheme = TabBarThemeData(labelColor: labelColor);
// Test material state label color. // Test material state label color.
await tester.pumpWidget(buildTabBar(tabBarTheme: tabBarTheme)); await tester.pumpWidget(buildTabBar(tabBarTheme: tabBarTheme));
@ -1620,7 +1620,7 @@ void main() {
expect(unselectedTextStyle.color, unselectedStateColor); expect(unselectedTextStyle.color, unselectedStateColor);
// Test labelColor & unselectedLabelColor override material state labelColor. // Test labelColor & unselectedLabelColor override material state labelColor.
tabBarTheme = const TabBarTheme( tabBarTheme = const TabBarThemeData(
labelColor: selectedColor, labelColor: selectedColor,
unselectedLabelColor: unselectedColor, unselectedLabelColor: unselectedColor,
); );
@ -1644,7 +1644,7 @@ void main() {
Widget buildTabs({ TextScaler? textScaler }) { Widget buildTabs({ TextScaler? textScaler }) {
return MaterialApp( return MaterialApp(
theme: ThemeData( theme: ThemeData(
tabBarTheme: TabBarTheme( tabBarTheme: TabBarThemeData(
textScaler: textScaler, textScaler: textScaler,
), ),
), ),
@ -1699,7 +1699,7 @@ void main() {
Widget buildTab({ TabIndicatorAnimation? indicatorAnimation }) { Widget buildTab({ TabIndicatorAnimation? indicatorAnimation }) {
return MaterialApp( return MaterialApp(
theme: ThemeData( theme: ThemeData(
tabBarTheme: TabBarTheme( tabBarTheme: TabBarThemeData(
indicatorAnimation: indicatorAnimation, indicatorAnimation: indicatorAnimation,
), ),
), ),

View File

@ -20,7 +20,7 @@ Widget boilerplate({
Widget? child, Widget? child,
TextDirection textDirection = TextDirection.ltr, TextDirection textDirection = TextDirection.ltr,
ThemeData? theme, ThemeData? theme,
TabBarTheme? tabBarTheme, TabBarThemeData? tabBarTheme,
bool? useMaterial3, bool? useMaterial3,
}) { }) {
return Theme( return Theme(
@ -52,7 +52,7 @@ Widget buildFrame({
EdgeInsetsGeometry? padding, EdgeInsetsGeometry? padding,
TextDirection textDirection = TextDirection.ltr, TextDirection textDirection = TextDirection.ltr,
TabAlignment? tabAlignment, TabAlignment? tabAlignment,
TabBarTheme? tabBarTheme, TabBarThemeData? tabBarTheme,
Decoration? indicator, Decoration? indicator,
bool? useMaterial3, bool? useMaterial3,
}) { }) {
@ -5536,7 +5536,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
theme: ThemeData( theme: ThemeData(
tabBarTheme: const TabBarTheme(labelPadding: labelPadding), tabBarTheme: const TabBarThemeData(labelPadding: labelPadding),
), ),
home: Scaffold( home: Scaffold(
appBar: AppBar( appBar: AppBar(
@ -5857,7 +5857,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
theme: ThemeData.light().copyWith( theme: ThemeData.light().copyWith(
tabBarTheme: TabBarTheme( tabBarTheme: TabBarThemeData(
splashFactory: splashFactory, splashFactory: splashFactory,
overlayColor: overlayColor, overlayColor: overlayColor,
)), )),
@ -6554,7 +6554,7 @@ void main() {
MaterialApp( MaterialApp(
theme: ThemeData( theme: ThemeData(
useMaterial3: true, useMaterial3: true,
tabBarTheme: const TabBarTheme(dividerColor: dividerColor), tabBarTheme: const TabBarThemeData(dividerColor: dividerColor),
), ),
home: Scaffold( home: Scaffold(
appBar: AppBar( appBar: AppBar(
@ -6583,7 +6583,7 @@ void main() {
MaterialApp( MaterialApp(
theme: ThemeData( theme: ThemeData(
useMaterial3: true, useMaterial3: true,
tabBarTheme: const TabBarTheme(dividerColor: dividerColor), tabBarTheme: const TabBarThemeData(dividerColor: dividerColor),
), ),
home: Scaffold( home: Scaffold(
body: DefaultTabController( body: DefaultTabController(
@ -6835,7 +6835,7 @@ void main() {
const String unSelectedValue = 'C'; const String unSelectedValue = 'C';
const Color labelColor = Color(0xff0000ff); const Color labelColor = Color(0xff0000ff);
await tester.pumpWidget( await tester.pumpWidget(
buildFrame(tabs: tabs, value: selectedValue, useMaterial3: false, tabBarTheme: const TabBarTheme(labelColor: labelColor)), buildFrame(tabs: tabs, value: selectedValue, useMaterial3: false, tabBarTheme: const TabBarThemeData(labelColor: labelColor)),
); );
expect(find.text('A'), findsOneWidget); expect(find.text('A'), findsOneWidget);
expect(find.text('B'), findsOneWidget); expect(find.text('B'), findsOneWidget);

View File

@ -919,7 +919,7 @@ void main() {
sliderTheme: sliderTheme, sliderTheme: sliderTheme,
snackBarTheme: const SnackBarThemeData(backgroundColor: Colors.black), snackBarTheme: const SnackBarThemeData(backgroundColor: Colors.black),
switchTheme: const SwitchThemeData(), switchTheme: const SwitchThemeData(),
tabBarTheme: const TabBarTheme(labelColor: Colors.black), tabBarTheme: const TabBarThemeData(labelColor: Colors.black),
textButtonTheme: TextButtonThemeData(style: TextButton.styleFrom(foregroundColor: Colors.red)), textButtonTheme: TextButtonThemeData(style: TextButton.styleFrom(foregroundColor: Colors.red)),
textSelectionTheme: const TextSelectionThemeData(cursorColor: Colors.black), textSelectionTheme: const TextSelectionThemeData(cursorColor: Colors.black),
timePickerTheme: const TimePickerThemeData(backgroundColor: Colors.black), timePickerTheme: const TimePickerThemeData(backgroundColor: Colors.black),
@ -1033,7 +1033,7 @@ void main() {
sliderTheme: otherSliderTheme, sliderTheme: otherSliderTheme,
snackBarTheme: const SnackBarThemeData(backgroundColor: Colors.white), snackBarTheme: const SnackBarThemeData(backgroundColor: Colors.white),
switchTheme: const SwitchThemeData(), switchTheme: const SwitchThemeData(),
tabBarTheme: const TabBarTheme(labelColor: Colors.white), tabBarTheme: const TabBarThemeData(labelColor: Colors.white),
textButtonTheme: const TextButtonThemeData(), textButtonTheme: const TextButtonThemeData(),
textSelectionTheme: const TextSelectionThemeData(cursorColor: Colors.white), textSelectionTheme: const TextSelectionThemeData(cursorColor: Colors.white),
timePickerTheme: const TimePickerThemeData(backgroundColor: Colors.white), timePickerTheme: const TimePickerThemeData(backgroundColor: Colors.white),