Fix transparent dividerColor
breaks TabBar.tabAlignment
(#150350)
fixes [`TabBar.tabAlignment` property does't work when `dividerColor` is transparent](https://github.com/flutter/flutter/issues/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`)  ### After (`dividerColor: Colors.transparent`, `tabAlignment: TabAlignment.start`) 
This commit is contained in:
parent
a9f554ac39
commit
33599006e7
@ -1025,6 +1025,8 @@ class TabBar extends StatefulWidget implements PreferredSizeWidget {
|
|||||||
|
|
||||||
/// The color of the divider.
|
/// The color of the divider.
|
||||||
///
|
///
|
||||||
|
/// If the [dividerColor] is [Colors.transparent], then the divider will not be drawn.
|
||||||
|
///
|
||||||
/// If null and [ThemeData.useMaterial3] is false, [TabBarTheme.dividerColor]
|
/// If null and [ThemeData.useMaterial3] is false, [TabBarTheme.dividerColor]
|
||||||
/// color is used. If that is null and [ThemeData.useMaterial3] is true,
|
/// color is used. If that is null and [ThemeData.useMaterial3] is true,
|
||||||
/// [ColorScheme.outlineVariant] will be used, otherwise divider will not be drawn.
|
/// [ColorScheme.outlineVariant] will be used, otherwise divider will not be drawn.
|
||||||
@ -1032,6 +1034,8 @@ class TabBar extends StatefulWidget implements PreferredSizeWidget {
|
|||||||
|
|
||||||
/// The height of the divider.
|
/// The height of the divider.
|
||||||
///
|
///
|
||||||
|
/// If the [dividerHeight] is zero or negative, then the divider will not be drawn.
|
||||||
|
///
|
||||||
/// If null and [ThemeData.useMaterial3] is true, [TabBarTheme.dividerHeight] is used.
|
/// If null and [ThemeData.useMaterial3] is true, [TabBarTheme.dividerHeight] is used.
|
||||||
/// If that is also null and [ThemeData.useMaterial3] is true, 1.0 will be used.
|
/// If that is also null and [ThemeData.useMaterial3] is true, 1.0 will be used.
|
||||||
/// Otherwise divider will not be drawn.
|
/// Otherwise divider will not be drawn.
|
||||||
@ -1813,19 +1817,18 @@ class _TabBarState extends State<TabBar> {
|
|||||||
|
|
||||||
final Color dividerColor = widget.dividerColor ?? tabBarTheme.dividerColor ?? _defaults.dividerColor!;
|
final Color dividerColor = widget.dividerColor ?? tabBarTheme.dividerColor ?? _defaults.dividerColor!;
|
||||||
final double dividerHeight = widget.dividerHeight ?? tabBarTheme.dividerHeight ?? _defaults.dividerHeight!;
|
final double dividerHeight = widget.dividerHeight ?? tabBarTheme.dividerHeight ?? _defaults.dividerHeight!;
|
||||||
final bool showDivider = dividerColor != Colors.transparent && dividerHeight > 0;
|
|
||||||
|
|
||||||
tabBar = Align(
|
tabBar = Align(
|
||||||
heightFactor: 1.0,
|
heightFactor: 1.0,
|
||||||
widthFactor: showDivider ? null : 1.0,
|
widthFactor: dividerHeight > 0 ? null : 1.0,
|
||||||
alignment: effectiveAlignment,
|
alignment: effectiveAlignment,
|
||||||
child: tabBar,
|
child: tabBar,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (showDivider) {
|
if (dividerColor != Colors.transparent && dividerHeight > 0) {
|
||||||
tabBar = CustomPaint(
|
tabBar = CustomPaint(
|
||||||
painter: _DividerPainter(
|
painter: _DividerPainter(
|
||||||
dividerColor: widget.dividerColor ?? tabBarTheme.dividerColor ?? _defaults.dividerColor!,
|
dividerColor: dividerColor,
|
||||||
dividerHeight: widget.dividerHeight ?? tabBarTheme.dividerHeight ?? _defaults.dividerHeight!,
|
dividerHeight: widget.dividerHeight ?? tabBarTheme.dividerHeight ?? _defaults.dividerHeight!,
|
||||||
),
|
),
|
||||||
child: tabBar,
|
child: tabBar,
|
||||||
|
@ -6722,30 +6722,6 @@ void main() {
|
|||||||
tabAlignment: TabAlignment.center,
|
tabAlignment: TabAlignment.center,
|
||||||
));
|
));
|
||||||
expect(tester.getSize(find.byType(TabBar)).width, 307.5);
|
expect(tester.getSize(find.byType(TabBar)).width, 307.5);
|
||||||
|
|
||||||
// Test default tab bar width when the divider color is set to transparent
|
|
||||||
// and tabAlignment is set to startOffset.
|
|
||||||
await tester.pumpWidget(buildTabBar(
|
|
||||||
dividerColor: Colors.transparent,
|
|
||||||
tabAlignment: TabAlignment.startOffset,
|
|
||||||
));
|
|
||||||
expect(tester.getSize(find.byType(TabBar)).width, 359.5);
|
|
||||||
|
|
||||||
// Test default tab bar width when the divider color is set to transparent
|
|
||||||
// and tabAlignment is set to start.
|
|
||||||
await tester.pumpWidget(buildTabBar(
|
|
||||||
dividerColor: Colors.transparent,
|
|
||||||
tabAlignment: TabAlignment.start,
|
|
||||||
));
|
|
||||||
expect(tester.getSize(find.byType(TabBar)).width, 307.5);
|
|
||||||
|
|
||||||
// Test default tab bar width when the divider color is set to transparent
|
|
||||||
// and tabAlignment is set to center.
|
|
||||||
await tester.pumpWidget(buildTabBar(
|
|
||||||
dividerColor: Colors.transparent,
|
|
||||||
tabAlignment: TabAlignment.center,
|
|
||||||
));
|
|
||||||
expect(tester.getSize(find.byType(TabBar)).width, 307.5);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
group('Material 2', () {
|
group('Material 2', () {
|
||||||
@ -7250,4 +7226,51 @@ void main() {
|
|||||||
expect(find.text('Page 3'), findsOneWidget);
|
expect(find.text('Page 3'), findsOneWidget);
|
||||||
expect(scrollable.controller!.position.pixels, equals(0.0));
|
expect(scrollable.controller!.position.pixels, equals(0.0));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// This is a regression test for https://github.com/flutter/flutter/issues/150316.
|
||||||
|
testWidgets('Scrollable TabBar wuth transparent divider expands to full width', (WidgetTester tester) async {
|
||||||
|
Widget buildTabBar({ Color? dividerColor, TabAlignment? tabAlignment }) {
|
||||||
|
return boilerplate(
|
||||||
|
child: Center(
|
||||||
|
child: DefaultTabController(
|
||||||
|
length: 3,
|
||||||
|
child: TabBar(
|
||||||
|
dividerColor: dividerColor,
|
||||||
|
tabAlignment: tabAlignment,
|
||||||
|
isScrollable: true,
|
||||||
|
tabs: const <Widget>[
|
||||||
|
Tab(text: 'Tab 1'),
|
||||||
|
Tab(text: 'Tab 2'),
|
||||||
|
Tab(text: 'Tab 3'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test default tab bar width when the divider color is set to transparent
|
||||||
|
// and tabAlignment is set to startOffset.
|
||||||
|
await tester.pumpWidget(buildTabBar(
|
||||||
|
dividerColor: Colors.transparent,
|
||||||
|
tabAlignment: TabAlignment.startOffset,
|
||||||
|
));
|
||||||
|
expect(tester.getSize(find.byType(TabBar)).width, 800.0);
|
||||||
|
|
||||||
|
// Test default tab bar width when the divider color is set to transparent
|
||||||
|
// and tabAlignment is set to start.
|
||||||
|
await tester.pumpWidget(buildTabBar(
|
||||||
|
dividerColor: Colors.transparent,
|
||||||
|
tabAlignment: TabAlignment.start,
|
||||||
|
));
|
||||||
|
expect(tester.getSize(find.byType(TabBar)).width, 800.0);
|
||||||
|
|
||||||
|
// Test default tab bar width when the divider color is set to transparent
|
||||||
|
// and tabAlignment is set to center.
|
||||||
|
await tester.pumpWidget(buildTabBar(
|
||||||
|
dividerColor: Colors.transparent,
|
||||||
|
tabAlignment: TabAlignment.center,
|
||||||
|
));
|
||||||
|
expect(tester.getSize(find.byType(TabBar)).width, 800.0);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user