Skip to content

Commit e317860

Browse files
authored
Normalize ThemeData.tabBarTheme (#156253)
Following #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 #91772
1 parent 12701dc commit e317860

File tree

6 files changed

+84
-65
lines changed

6 files changed

+84
-65
lines changed

packages/flutter/lib/src/material/tab_bar_theme.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,9 +245,9 @@ class TabBarTheme extends InheritedTheme with Diagnosticable {
245245
}
246246

247247
/// Returns the closest [TabBarTheme] instance given the build context.
248-
static TabBarTheme of(BuildContext context) {
248+
static TabBarThemeData of(BuildContext context) {
249249
final TabBarTheme? tabBarTheme = context.dependOnInheritedWidgetOfExactType<TabBarTheme>();
250-
return tabBarTheme ?? Theme.of(context).tabBarTheme;
250+
return tabBarTheme?.data ?? Theme.of(context).tabBarTheme;
251251
}
252252

253253
/// Linearly interpolate between two tab bar themes.

packages/flutter/lib/src/material/tabs.dart

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ class _TabStyle extends AnimatedWidget {
246246

247247
MaterialStateColor _resolveWithLabelColor(BuildContext context) {
248248
final ThemeData themeData = Theme.of(context);
249-
final TabBarThemeData tabBarTheme = TabBarTheme.of(context).data;
249+
final TabBarThemeData tabBarTheme = TabBarTheme.of(context);
250250
final Animation<double> animation = listenable as Animation<double>;
251251

252252
// labelStyle.color (and tabBarTheme.labelStyle.color) is not considered
@@ -285,7 +285,7 @@ class _TabStyle extends AnimatedWidget {
285285

286286
@override
287287
Widget build(BuildContext context) {
288-
final TabBarThemeData tabBarTheme = TabBarTheme.of(context).data;
288+
final TabBarThemeData tabBarTheme = TabBarTheme.of(context);
289289
final Animation<double> animation = listenable as Animation<double>;
290290

291291
final Set<MaterialState> states = isSelected
@@ -1355,7 +1355,7 @@ class _TabBarState extends State<TabBar> {
13551355

13561356
Decoration _getIndicator(TabBarIndicatorSize indicatorSize) {
13571357
final ThemeData theme = Theme.of(context);
1358-
final TabBarThemeData tabBarTheme = TabBarTheme.of(context).data;
1358+
final TabBarThemeData tabBarTheme = TabBarTheme.of(context);
13591359

13601360
if (widget.indicator != null) {
13611361
return widget.indicator!;
@@ -1455,7 +1455,7 @@ class _TabBarState extends State<TabBar> {
14551455

14561456
void _initIndicatorPainter() {
14571457
final ThemeData theme = Theme.of(context);
1458-
final TabBarTheme tabBarTheme = TabBarTheme.of(context);
1458+
final TabBarThemeData tabBarTheme = TabBarTheme.of(context);
14591459
final TabBarIndicatorSize indicatorSize = widget.indicatorSize
14601460
?? tabBarTheme.indicatorSize
14611461
?? _defaults.indicatorSize!;
@@ -1687,7 +1687,7 @@ class _TabBarState extends State<TabBar> {
16871687
assert(debugCheckHasMaterialLocalizations(context));
16881688
assert(_debugScheduleCheckHasValidTabsCount());
16891689
final ThemeData theme = Theme.of(context);
1690-
final TabBarThemeData tabBarTheme = TabBarTheme.of(context).data;
1690+
final TabBarThemeData tabBarTheme = TabBarTheme.of(context);
16911691
final TabAlignment effectiveTabAlignment = widget.tabAlignment ?? tabBarTheme.tabAlignment ?? _defaults.tabAlignment!;
16921692
assert(_debugTabAlignmentIsValid(effectiveTabAlignment));
16931693

packages/flutter/lib/src/material/theme_data.dart

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,8 @@ class ThemeData with Diagnosticable {
348348
SliderThemeData? sliderTheme,
349349
SnackBarThemeData? snackBarTheme,
350350
SwitchThemeData? switchTheme,
351-
TabBarTheme? tabBarTheme,
351+
// TODO(QuncCccccc): Change the parameter type to TabBarThemeData
352+
Object? tabBarTheme,
352353
TextButtonThemeData? textButtonTheme,
353354
TextSelectionThemeData? textSelectionTheme,
354355
TimePickerThemeData? timePickerTheme,
@@ -541,7 +542,15 @@ class ThemeData with Diagnosticable {
541542
sliderTheme ??= const SliderThemeData();
542543
snackBarTheme ??= const SnackBarThemeData();
543544
switchTheme ??= const SwitchThemeData();
544-
tabBarTheme ??= const TabBarTheme();
545+
// TODO(QuncCccccc): Clean this up once the type of `tabBarTheme` is changed to `TabBarThemeData`
546+
if (tabBarTheme != null) {
547+
if (tabBarTheme is TabBarTheme) {
548+
tabBarTheme = tabBarTheme.data;
549+
} else if (tabBarTheme is! TabBarThemeData) {
550+
throw ArgumentError('tabBarTheme must be either a TabBarThemeData or a TabBarTheme');
551+
}
552+
}
553+
tabBarTheme ??= const TabBarThemeData();
545554
textButtonTheme ??= const TextButtonThemeData();
546555
textSelectionTheme ??= const TextSelectionThemeData();
547556
timePickerTheme ??= const TimePickerThemeData();
@@ -634,7 +643,7 @@ class ThemeData with Diagnosticable {
634643
sliderTheme: sliderTheme,
635644
snackBarTheme: snackBarTheme,
636645
switchTheme: switchTheme,
637-
tabBarTheme: tabBarTheme,
646+
tabBarTheme: tabBarTheme as TabBarThemeData,
638647
textButtonTheme: textButtonTheme,
639648
textSelectionTheme: textSelectionTheme,
640649
timePickerTheme: timePickerTheme,
@@ -1387,7 +1396,7 @@ class ThemeData with Diagnosticable {
13871396
final SwitchThemeData switchTheme;
13881397

13891398
/// A theme for customizing the size, shape, and color of the tab bar indicator.
1390-
final TabBarTheme tabBarTheme;
1399+
final TabBarThemeData tabBarTheme;
13911400

13921401
/// A theme for customizing the appearance and internal layout of
13931402
/// [TextButton]s.
@@ -1507,7 +1516,8 @@ class ThemeData with Diagnosticable {
15071516
SliderThemeData? sliderTheme,
15081517
SnackBarThemeData? snackBarTheme,
15091518
SwitchThemeData? switchTheme,
1510-
TabBarTheme? tabBarTheme,
1519+
// TODO(QuncCccccc): Change the parameter type to TabBarThemeData
1520+
Object? tabBarTheme,
15111521
TextButtonThemeData? textButtonTheme,
15121522
TextSelectionThemeData? textSelectionTheme,
15131523
TimePickerThemeData? timePickerTheme,
@@ -1547,6 +1557,15 @@ class ThemeData with Diagnosticable {
15471557
throw ArgumentError('dialogTheme must be either a DialogThemeData or a DialogTheme');
15481558
}
15491559
}
1560+
1561+
// TODO(QuncCccccc): Clean this up once the type of `tabBarTheme` is changed to `TabBarThemeData`
1562+
if (tabBarTheme != null) {
1563+
if (tabBarTheme is TabBarTheme) {
1564+
tabBarTheme = tabBarTheme.data;
1565+
} else if (tabBarTheme is! TabBarThemeData) {
1566+
throw ArgumentError('tabBarTheme must be either a TabBarThemeData or a TabBarTheme');
1567+
}
1568+
}
15501569
return ThemeData.raw(
15511570
// For the sanity of the reader, make sure these properties are in the same
15521571
// order in every place that they are separated by section comments (e.g.
@@ -1634,7 +1653,7 @@ class ThemeData with Diagnosticable {
16341653
sliderTheme: sliderTheme ?? this.sliderTheme,
16351654
snackBarTheme: snackBarTheme ?? this.snackBarTheme,
16361655
switchTheme: switchTheme ?? this.switchTheme,
1637-
tabBarTheme: tabBarTheme ?? this.tabBarTheme,
1656+
tabBarTheme: tabBarTheme as TabBarThemeData? ?? this.tabBarTheme,
16381657
textButtonTheme: textButtonTheme ?? this.textButtonTheme,
16391658
textSelectionTheme: textSelectionTheme ?? this.textSelectionTheme,
16401659
timePickerTheme: timePickerTheme ?? this.timePickerTheme,
@@ -1827,7 +1846,7 @@ class ThemeData with Diagnosticable {
18271846
sliderTheme: SliderThemeData.lerp(a.sliderTheme, b.sliderTheme, t),
18281847
snackBarTheme: SnackBarThemeData.lerp(a.snackBarTheme, b.snackBarTheme, t),
18291848
switchTheme: SwitchThemeData.lerp(a.switchTheme, b.switchTheme, t),
1830-
tabBarTheme: TabBarTheme.lerp(a.tabBarTheme, b.tabBarTheme, t),
1849+
tabBarTheme: TabBarThemeData.lerp(a.tabBarTheme, b.tabBarTheme, t),
18311850
textButtonTheme: TextButtonThemeData.lerp(a.textButtonTheme, b.textButtonTheme, t)!,
18321851
textSelectionTheme: TextSelectionThemeData.lerp(a.textSelectionTheme, b.textSelectionTheme, t)!,
18331852
timePickerTheme: TimePickerThemeData.lerp(a.timePickerTheme, b.timePickerTheme, t),
@@ -2125,7 +2144,7 @@ class ThemeData with Diagnosticable {
21252144
properties.add(DiagnosticsProperty<SliderThemeData>('sliderTheme', sliderTheme, level: DiagnosticLevel.debug));
21262145
properties.add(DiagnosticsProperty<SnackBarThemeData>('snackBarTheme', snackBarTheme, defaultValue: defaultData.snackBarTheme, level: DiagnosticLevel.debug));
21272146
properties.add(DiagnosticsProperty<SwitchThemeData>('switchTheme', switchTheme, defaultValue: defaultData.switchTheme, level: DiagnosticLevel.debug));
2128-
properties.add(DiagnosticsProperty<TabBarTheme>('tabBarTheme', tabBarTheme, level: DiagnosticLevel.debug));
2147+
properties.add(DiagnosticsProperty<TabBarThemeData>('tabBarTheme', tabBarTheme, level: DiagnosticLevel.debug));
21292148
properties.add(DiagnosticsProperty<TextButtonThemeData>('textButtonTheme', textButtonTheme, defaultValue: defaultData.textButtonTheme, level: DiagnosticLevel.debug));
21302149
properties.add(DiagnosticsProperty<TextSelectionThemeData>('textSelectionTheme', textSelectionTheme, defaultValue: defaultData.textSelectionTheme, level: DiagnosticLevel.debug));
21312150
properties.add(DiagnosticsProperty<TimePickerThemeData>('timePickerTheme', timePickerTheme, defaultValue: defaultData.timePickerTheme, level: DiagnosticLevel.debug));

0 commit comments

Comments
 (0)