Fix TabBarTheme.indicatorColor
not applied in Material 2 (#132123)
fixes [[Proposal] Improve TabBarTheme styling API for indicator color ](https://github.com/flutter/flutter/issues/130392) ### Description This fixes an issue where the `TabBarTheme.indicator` isn't applied in Material 2 and also adds indicator color tests for both M3 and M2. ### Code sample <details> <summary>expand to view the code sample</summary> ```dart import 'package:flutter/material.dart'; /// Flutter code sample for [TabBar]. void main() => runApp(const TabBarApp()); class TabBarApp extends StatelessWidget { const TabBarApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( theme: ThemeData( useMaterial3: false, tabBarTheme: const TabBarTheme( indicatorColor: Colors.amber, ) ), home: const TabBarExample(), ); } } class TabBarExample extends StatelessWidget { const TabBarExample({super.key}); @override Widget build(BuildContext context) { return DefaultTabController( initialIndex: 1, length: 3, child: Scaffold( appBar: AppBar( title: const Text('TabBar Sample'), bottom: const TabBar( tabs: <Widget>[ Tab( icon: Icon(Icons.cloud_outlined), text: 'Cloudy', ), Tab( icon: Icon(Icons.beach_access_sharp), text: 'Sunny', ), Tab( icon: Icon(Icons.brightness_5_sharp), text: 'Rainy', ), ], ), ), body: const TabBarView( children: <Widget>[ Center( child: Text("It's cloudy here"), ), Center( child: Text("It's rainy here"), ), Center( child: Text("It's sunny here"), ), ], ), ), ); } } ``` </details> ### Before  ### After 
This commit is contained in:
parent
0b81347897
commit
ee47267d26
@ -1220,10 +1220,7 @@ class _TabBarState extends State<TabBar> {
|
|||||||
return tabBarTheme.indicator!;
|
return tabBarTheme.indicator!;
|
||||||
}
|
}
|
||||||
|
|
||||||
Color color = widget.indicatorColor
|
Color color = widget.indicatorColor ?? tabBarTheme.indicatorColor ?? _defaults.indicatorColor!;
|
||||||
?? (theme.useMaterial3
|
|
||||||
? tabBarTheme.indicatorColor ?? _defaults.indicatorColor!
|
|
||||||
: Theme.of(context).indicatorColor);
|
|
||||||
// ThemeData tries to avoid this by having indicatorColor avoid being the
|
// ThemeData tries to avoid this by having indicatorColor avoid being the
|
||||||
// primaryColor. However, it's possible that the tab bar is on a
|
// primaryColor. However, it's possible that the tab bar is on a
|
||||||
// Material that isn't the primaryColor. In that case, if the indicator
|
// Material that isn't the primaryColor. In that case, if the indicator
|
||||||
|
@ -1132,4 +1132,90 @@ void main() {
|
|||||||
expect(tabTwoRect.right, equals(tabTwoRight));
|
expect(tabTwoRect.right, equals(tabTwoRight));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('Material3 - TabBar indicator respects TabBarTheme.indicatorColor', (WidgetTester tester) async {
|
||||||
|
final List<Widget> tabs = List<Widget>.generate(4, (int index) {
|
||||||
|
return Tab(text: 'Tab $index');
|
||||||
|
});
|
||||||
|
|
||||||
|
final TabController controller = TabController(
|
||||||
|
vsync: const TestVSync(),
|
||||||
|
length: tabs.length,
|
||||||
|
);
|
||||||
|
|
||||||
|
const Color tabBarThemeIndicatorColor = Color(0xffff0000);
|
||||||
|
|
||||||
|
Widget buildTabBar({ required ThemeData theme }) {
|
||||||
|
return MaterialApp(
|
||||||
|
theme: theme,
|
||||||
|
home: Material(
|
||||||
|
child: Container(
|
||||||
|
alignment: Alignment.topLeft,
|
||||||
|
child: TabBar(
|
||||||
|
controller: controller,
|
||||||
|
tabs: tabs,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await tester.pumpWidget(buildTabBar(theme: ThemeData(useMaterial3: true)));
|
||||||
|
|
||||||
|
RenderBox tabBarBox = tester.firstRenderObject<RenderBox>(find.byType(TabBar));
|
||||||
|
expect(tabBarBox,paints..rrect(color: ThemeData(useMaterial3: true).colorScheme.primary));
|
||||||
|
|
||||||
|
await tester.pumpWidget(buildTabBar(theme: ThemeData(
|
||||||
|
useMaterial3: true,
|
||||||
|
tabBarTheme: const TabBarTheme(indicatorColor: tabBarThemeIndicatorColor)
|
||||||
|
)));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
tabBarBox = tester.firstRenderObject<RenderBox>(find.byType(TabBar));
|
||||||
|
expect(tabBarBox,paints..rrect(color: tabBarThemeIndicatorColor));
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('Material2 - TabBar indicator respects TabBarTheme.indicatorColor', (WidgetTester tester) async {
|
||||||
|
final List<Widget> tabs = List<Widget>.generate(4, (int index) {
|
||||||
|
return Tab(text: 'Tab $index');
|
||||||
|
});
|
||||||
|
|
||||||
|
final TabController controller = TabController(
|
||||||
|
vsync: const TestVSync(),
|
||||||
|
length: tabs.length,
|
||||||
|
);
|
||||||
|
|
||||||
|
const Color themeIndicatorColor = Color(0xffff0000);
|
||||||
|
const Color tabBarThemeIndicatorColor = Color(0xffffff00);
|
||||||
|
|
||||||
|
Widget buildTabBar({ Color? themeIndicatorColor, Color? tabBarThemeIndicatorColor }) {
|
||||||
|
return MaterialApp(
|
||||||
|
theme: ThemeData(
|
||||||
|
indicatorColor: themeIndicatorColor,
|
||||||
|
tabBarTheme: TabBarTheme(indicatorColor: tabBarThemeIndicatorColor),
|
||||||
|
useMaterial3: false,
|
||||||
|
),
|
||||||
|
home: Material(
|
||||||
|
child: Container(
|
||||||
|
alignment: Alignment.topLeft,
|
||||||
|
child: TabBar(
|
||||||
|
controller: controller,
|
||||||
|
tabs: tabs,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await tester.pumpWidget(buildTabBar(themeIndicatorColor: themeIndicatorColor));
|
||||||
|
|
||||||
|
RenderBox tabBarBox = tester.firstRenderObject<RenderBox>(find.byType(TabBar));
|
||||||
|
expect(tabBarBox,paints..line(color: themeIndicatorColor));
|
||||||
|
|
||||||
|
await tester.pumpWidget(buildTabBar(tabBarThemeIndicatorColor: tabBarThemeIndicatorColor));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
tabBarBox = tester.firstRenderObject<RenderBox>(find.byType(TabBar));
|
||||||
|
expect(tabBarBox,paints..line(color: tabBarThemeIndicatorColor));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
@ -488,7 +488,6 @@ void main() {
|
|||||||
|
|
||||||
const double indicatorWeight = 3.0;
|
const double indicatorWeight = 3.0;
|
||||||
|
|
||||||
|
|
||||||
final RRect rrect = ui.ParagraphBuilder.shouldDisableRoundingHack
|
final RRect rrect = ui.ParagraphBuilder.shouldDisableRoundingHack
|
||||||
? RRect.fromLTRBAndCorners(
|
? RRect.fromLTRBAndCorners(
|
||||||
64.75,
|
64.75,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user