@@ -15,6 +15,7 @@ import 'color_scheme.dart';
15
15
import 'colors.dart' ;
16
16
import 'constants.dart' ;
17
17
import 'debug.dart' ;
18
+ import 'divider.dart' ;
18
19
import 'ink_well.dart' ;
19
20
import 'material.dart' ;
20
21
import 'material_localizations.dart' ;
@@ -360,7 +361,6 @@ class _IndicatorPainter extends CustomPainter {
360
361
required _IndicatorPainter ? old,
361
362
required this .indicatorPadding,
362
363
required this .labelPaddings,
363
- this .dividerColor,
364
364
}) : super (repaint: controller.animation) {
365
365
if (old != null ) {
366
366
saveTabOffsets (old._currentTabOffsets, old._currentTextDirection);
@@ -372,7 +372,6 @@ class _IndicatorPainter extends CustomPainter {
372
372
final TabBarIndicatorSize ? indicatorSize;
373
373
final EdgeInsetsGeometry indicatorPadding;
374
374
final List <GlobalKey > tabKeys;
375
- final Color ? dividerColor;
376
375
final List <EdgeInsetsGeometry > labelPaddings;
377
376
378
377
// _currentTabOffsets and _currentTextDirection are set each time TabBar
@@ -465,10 +464,6 @@ class _IndicatorPainter extends CustomPainter {
465
464
size: _currentRect! .size,
466
465
textDirection: _currentTextDirection,
467
466
);
468
- if (dividerColor != null ) {
469
- final Paint dividerPaint = Paint ()..color = dividerColor! ..strokeWidth = 1 ;
470
- canvas.drawLine (Offset (0 , size.height), Offset (size.width, size.height), dividerPaint);
471
- }
472
467
_painter! .paint (canvas, _currentRect! .topLeft, configuration);
473
468
}
474
469
@@ -682,6 +677,7 @@ class TabBar extends StatefulWidget implements PreferredSizeWidget {
682
677
this .indicator,
683
678
this .indicatorSize,
684
679
this .dividerColor,
680
+ this .dividerHeight,
685
681
this .labelColor,
686
682
this .labelStyle,
687
683
this .labelPadding,
@@ -731,6 +727,7 @@ class TabBar extends StatefulWidget implements PreferredSizeWidget {
731
727
this .indicator,
732
728
this .indicatorSize,
733
729
this .dividerColor,
730
+ this .dividerHeight,
734
731
this .labelColor,
735
732
this .labelStyle,
736
733
this .labelPadding,
@@ -849,6 +846,13 @@ class TabBar extends StatefulWidget implements PreferredSizeWidget {
849
846
/// [ColorScheme.surfaceVariant] will be used, otherwise divider will not be drawn.
850
847
final Color ? dividerColor;
851
848
849
+ /// The height of the divider.
850
+ ///
851
+ /// If null and [ThemeData.useMaterial3] is true, [TabBarTheme.dividerHeight]
852
+ /// is used. If that is null and [ThemeData.useMaterial3] is true, 1.0 will be used.
853
+ /// Otherwise divider will not be drawn.
854
+ final double ? dividerHeight;
855
+
852
856
/// The color of selected tab labels.
853
857
///
854
858
/// If null, then [TabBarTheme.labelColor] is used. If that is also null and
@@ -1096,7 +1100,7 @@ class _TabBarState extends State<TabBar> {
1096
1100
}
1097
1101
}
1098
1102
1099
- Decoration _getIndicator () {
1103
+ Decoration _getIndicator (TabBarIndicatorSize indicatorSize ) {
1100
1104
final ThemeData theme = Theme .of (context);
1101
1105
final TabBarTheme tabBarTheme = TabBarTheme .of (context);
1102
1106
@@ -1130,17 +1134,24 @@ class _TabBarState extends State<TabBar> {
1130
1134
color = Colors .white;
1131
1135
}
1132
1136
1133
- return UnderlineTabIndicator (
1134
- borderRadius: theme.useMaterial3 && widget._isPrimary
1137
+ if (theme.useMaterial3 && widget._isPrimary && indicatorSize == TabBarIndicatorSize .label) {
1138
+ return UnderlineTabIndicator (
1139
+ borderRadius: const BorderRadius .only (
1140
+ topLeft: Radius .circular (3.0 ),
1141
+ topRight: Radius .circular (3.0 ),
1142
+ ),
1143
+ borderSide: BorderSide (
1135
1144
// TODO(tahatesser): Make sure this value matches Material 3 Tabs spec
1136
1145
// when `preferredSize`and `indicatorWeight` are updated to support Material 3
1137
1146
// https://m3.material.io/components/tabs/specs#149a189f-9039-4195-99da-15c205d20e30,
1138
1147
// https://github.com/flutter/flutter/issues/116136
1139
- ? const BorderRadius .only (
1140
- topLeft: Radius .circular (3.0 ),
1141
- topRight: Radius .circular (3.0 ),
1142
- )
1143
- : null ,
1148
+ width: widget.indicatorWeight,
1149
+ color: color,
1150
+ ),
1151
+ );
1152
+ }
1153
+
1154
+ return UnderlineTabIndicator (
1144
1155
borderSide: BorderSide (
1145
1156
width: widget.indicatorWeight,
1146
1157
color: color,
@@ -1185,17 +1196,18 @@ class _TabBarState extends State<TabBar> {
1185
1196
}
1186
1197
1187
1198
void _initIndicatorPainter () {
1188
- final ThemeData theme = Theme .of (context);
1189
1199
final TabBarTheme tabBarTheme = TabBarTheme .of (context);
1200
+ final TabBarIndicatorSize indicatorSize = widget.indicatorSize
1201
+ ?? tabBarTheme.indicatorSize
1202
+ ?? _defaults.indicatorSize! ;
1190
1203
1191
1204
_indicatorPainter = ! _controllerIsValid ? null : _IndicatorPainter (
1192
1205
controller: _controller! ,
1193
- indicator: _getIndicator (),
1194
- indicatorSize: widget. indicatorSize ?? tabBarTheme.indicatorSize ?? _defaults.indicatorSize ! ,
1206
+ indicator: _getIndicator (indicatorSize ),
1207
+ indicatorSize: indicatorSize,
1195
1208
indicatorPadding: widget.indicatorPadding,
1196
1209
tabKeys: _tabKeys,
1197
1210
old: _indicatorPainter,
1198
- dividerColor: theme.useMaterial3 ? widget.dividerColor ?? tabBarTheme.dividerColor ?? _defaults.dividerColor : null ,
1199
1211
labelPaddings: _labelPaddings,
1200
1212
);
1201
1213
}
@@ -1390,6 +1402,7 @@ class _TabBarState extends State<TabBar> {
1390
1402
);
1391
1403
}
1392
1404
1405
+ final ThemeData theme = Theme .of (context);
1393
1406
final TabBarTheme tabBarTheme = TabBarTheme .of (context);
1394
1407
1395
1408
final List <Widget > wrappedTabs = List <Widget >.generate (widget.tabs.length, (int index) {
@@ -1535,6 +1548,24 @@ class _TabBarState extends State<TabBar> {
1535
1548
);
1536
1549
}
1537
1550
1551
+ if (theme.useMaterial3) {
1552
+ tabBar = Stack (
1553
+ alignment: Alignment .center,
1554
+ children: < Widget > [
1555
+ Container (
1556
+ height: widget.preferredSize.height,
1557
+ alignment: Alignment .bottomCenter,
1558
+ child: Divider (
1559
+ height: 0 ,
1560
+ thickness: widget.dividerHeight ?? tabBarTheme.dividerHeight ?? _defaults.dividerHeight,
1561
+ color: widget.dividerColor ?? tabBarTheme.dividerColor ?? _defaults.dividerColor,
1562
+ ),
1563
+ ),
1564
+ tabBar,
1565
+ ],
1566
+ );
1567
+ }
1568
+
1538
1569
return tabBar;
1539
1570
}
1540
1571
}
@@ -2068,6 +2099,9 @@ class _TabsPrimaryDefaultsM3 extends TabBarTheme {
2068
2099
late final ColorScheme _colors = Theme .of (context).colorScheme;
2069
2100
late final TextTheme _textTheme = Theme .of (context).textTheme;
2070
2101
2102
+ @override
2103
+ double ? get dividerHeight => 1.0 ;
2104
+
2071
2105
@override
2072
2106
Color ? get dividerColor => _colors.surfaceVariant;
2073
2107
@@ -2129,6 +2163,9 @@ class _TabsSecondaryDefaultsM3 extends TabBarTheme {
2129
2163
@override
2130
2164
Color ? get dividerColor => _colors.surfaceVariant;
2131
2165
2166
+ @override
2167
+ double ? get dividerHeight => 1.0 ;
2168
+
2132
2169
@override
2133
2170
Color ? get indicatorColor => _colors.primary;
2134
2171
0 commit comments