Skip to content

Commit 3359900

Browse files
authored
Fix transparent dividerColor breaks TabBar.tabAlignment (flutter#150350)
fixes [`TabBar.tabAlignment` property does't work when `dividerColor` is transparent](flutter#150316) ### Code sample <details> <summary>expand to view the code sample</summary> ```dart import 'package:flutter/material.dart'; void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({super.key}); @OverRide Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, home: DefaultTabController( length: 2, child: Scaffold( appBar: AppBar( title: const Text('TabBar'), bottom: const TabBar( dividerColor: Colors.transparent, tabAlignment: TabAlignment.start, isScrollable: true, tabs: <Widget>[ Tab(text: 'TAB 1'), Tab(text: 'TAB 2'), ], ), ), body: const TabBarView( children: <Widget>[ SizedBox.expand(), SizedBox.expand(), ], ), floatingActionButton: FloatingActionButton( onPressed: () {}, child: const Icon(Icons.add), ), ), ), ); } } ``` </details> ### Before (`dividerColor: Colors.transparent`, `tabAlignment: TabAlignment.start`) ![Screenshot 2024-06-17 at 15 44 33](https://github.com/flutter/flutter/assets/48603081/a60e88c7-fd99-4444-b7e5-1bceacc22f4c) ### After (`dividerColor: Colors.transparent`, `tabAlignment: TabAlignment.start`) ![Screenshot 2024-06-17 at 15 44 55](https://github.com/flutter/flutter/assets/48603081/aa003d65-107f-4618-be29-095ab2660374)
1 parent a9f554a commit 3359900

File tree

2 files changed

+54
-28
lines changed

2 files changed

+54
-28
lines changed

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,13 +1025,17 @@ class TabBar extends StatefulWidget implements PreferredSizeWidget {
10251025

10261026
/// The color of the divider.
10271027
///
1028+
/// If the [dividerColor] is [Colors.transparent], then the divider will not be drawn.
1029+
///
10281030
/// If null and [ThemeData.useMaterial3] is false, [TabBarTheme.dividerColor]
10291031
/// color is used. If that is null and [ThemeData.useMaterial3] is true,
10301032
/// [ColorScheme.outlineVariant] will be used, otherwise divider will not be drawn.
10311033
final Color? dividerColor;
10321034

10331035
/// The height of the divider.
10341036
///
1037+
/// If the [dividerHeight] is zero or negative, then the divider will not be drawn.
1038+
///
10351039
/// If null and [ThemeData.useMaterial3] is true, [TabBarTheme.dividerHeight] is used.
10361040
/// If that is also null and [ThemeData.useMaterial3] is true, 1.0 will be used.
10371041
/// Otherwise divider will not be drawn.
@@ -1813,19 +1817,18 @@ class _TabBarState extends State<TabBar> {
18131817

18141818
final Color dividerColor = widget.dividerColor ?? tabBarTheme.dividerColor ?? _defaults.dividerColor!;
18151819
final double dividerHeight = widget.dividerHeight ?? tabBarTheme.dividerHeight ?? _defaults.dividerHeight!;
1816-
final bool showDivider = dividerColor != Colors.transparent && dividerHeight > 0;
18171820

18181821
tabBar = Align(
18191822
heightFactor: 1.0,
1820-
widthFactor: showDivider ? null : 1.0,
1823+
widthFactor: dividerHeight > 0 ? null : 1.0,
18211824
alignment: effectiveAlignment,
18221825
child: tabBar,
18231826
);
18241827

1825-
if (showDivider) {
1828+
if (dividerColor != Colors.transparent && dividerHeight > 0) {
18261829
tabBar = CustomPaint(
18271830
painter: _DividerPainter(
1828-
dividerColor: widget.dividerColor ?? tabBarTheme.dividerColor ?? _defaults.dividerColor!,
1831+
dividerColor: dividerColor,
18291832
dividerHeight: widget.dividerHeight ?? tabBarTheme.dividerHeight ?? _defaults.dividerHeight!,
18301833
),
18311834
child: tabBar,

packages/flutter/test/material/tabs_test.dart

Lines changed: 47 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6722,30 +6722,6 @@ void main() {
67226722
tabAlignment: TabAlignment.center,
67236723
));
67246724
expect(tester.getSize(find.byType(TabBar)).width, 307.5);
6725-
6726-
// Test default tab bar width when the divider color is set to transparent
6727-
// and tabAlignment is set to startOffset.
6728-
await tester.pumpWidget(buildTabBar(
6729-
dividerColor: Colors.transparent,
6730-
tabAlignment: TabAlignment.startOffset,
6731-
));
6732-
expect(tester.getSize(find.byType(TabBar)).width, 359.5);
6733-
6734-
// Test default tab bar width when the divider color is set to transparent
6735-
// and tabAlignment is set to start.
6736-
await tester.pumpWidget(buildTabBar(
6737-
dividerColor: Colors.transparent,
6738-
tabAlignment: TabAlignment.start,
6739-
));
6740-
expect(tester.getSize(find.byType(TabBar)).width, 307.5);
6741-
6742-
// Test default tab bar width when the divider color is set to transparent
6743-
// and tabAlignment is set to center.
6744-
await tester.pumpWidget(buildTabBar(
6745-
dividerColor: Colors.transparent,
6746-
tabAlignment: TabAlignment.center,
6747-
));
6748-
expect(tester.getSize(find.byType(TabBar)).width, 307.5);
67496725
});
67506726

67516727
group('Material 2', () {
@@ -7250,4 +7226,51 @@ void main() {
72507226
expect(find.text('Page 3'), findsOneWidget);
72517227
expect(scrollable.controller!.position.pixels, equals(0.0));
72527228
});
7229+
7230+
// This is a regression test for https://github.com/flutter/flutter/issues/150316.
7231+
testWidgets('Scrollable TabBar wuth transparent divider expands to full width', (WidgetTester tester) async {
7232+
Widget buildTabBar({ Color? dividerColor, TabAlignment? tabAlignment }) {
7233+
return boilerplate(
7234+
child: Center(
7235+
child: DefaultTabController(
7236+
length: 3,
7237+
child: TabBar(
7238+
dividerColor: dividerColor,
7239+
tabAlignment: tabAlignment,
7240+
isScrollable: true,
7241+
tabs: const <Widget>[
7242+
Tab(text: 'Tab 1'),
7243+
Tab(text: 'Tab 2'),
7244+
Tab(text: 'Tab 3'),
7245+
],
7246+
),
7247+
),
7248+
),
7249+
);
7250+
}
7251+
7252+
// Test default tab bar width when the divider color is set to transparent
7253+
// and tabAlignment is set to startOffset.
7254+
await tester.pumpWidget(buildTabBar(
7255+
dividerColor: Colors.transparent,
7256+
tabAlignment: TabAlignment.startOffset,
7257+
));
7258+
expect(tester.getSize(find.byType(TabBar)).width, 800.0);
7259+
7260+
// Test default tab bar width when the divider color is set to transparent
7261+
// and tabAlignment is set to start.
7262+
await tester.pumpWidget(buildTabBar(
7263+
dividerColor: Colors.transparent,
7264+
tabAlignment: TabAlignment.start,
7265+
));
7266+
expect(tester.getSize(find.byType(TabBar)).width, 800.0);
7267+
7268+
// Test default tab bar width when the divider color is set to transparent
7269+
// and tabAlignment is set to center.
7270+
await tester.pumpWidget(buildTabBar(
7271+
dividerColor: Colors.transparent,
7272+
tabAlignment: TabAlignment.center,
7273+
));
7274+
expect(tester.getSize(find.byType(TabBar)).width, 800.0);
7275+
});
72537276
}

0 commit comments

Comments
 (0)