Unverified Commit 88016c11 authored by Taha Tesser's avatar Taha Tesser Committed by GitHub

Fix scrollable `TabBar` expands to full width when the divider is removed (#140963)

fixes [TabBar Expands to full width of the screen isScrollable: true after upgrading to flutter 3.16.4](https://github.com/flutter/flutter/issues/140338)

---

## Description

Fixes the scrollable `TabBar` width when the divider is removed. (when the divider height is set to `0` or divider color is set to `Colors.transparent`)

### 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) {
    const int tabsCount = 2;

    return MaterialApp(
      home: DefaultTabController(
        initialIndex: 1,
        length: tabsCount,
        child: Scaffold(
          appBar: AppBar(
            title: const Text('TabBar Sample'),
            bottom: PreferredSize(
              preferredSize: const Size.fromHeight(48.0),
              child: ColoredBox(
                color: Theme.of(context).colorScheme.secondaryContainer,
                child:  TabBar(
                  // dividerColor: Theme.of(context).colorScheme.onSurface,
                  dividerColor: Colors.transparent, // remove divider
                  // dividerHeight: 0, // remove divider
                  isScrollable: true,
                  tabAlignment: TabAlignment.center,
                  tabs: <Widget>[
                    for (int i = 0; i < tabsCount; i++)
                      Tab(
                        text: 'Tab $i',
                      ),
                  ],
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}
```

</details>

### Before
![Simulator Screenshot - iPhone 15 Pro - 2024-01-04 at 15 16 15](https://github.com/flutter/flutter/assets/48603081/b776e7e6-e5f0-49df-8a79-55032eaad631)

### After
![Simulator Screenshot - iPhone 15 Pro - 2024-01-04 at 15 16 23](https://github.com/flutter/flutter/assets/48603081/9ad13793-43a9-4ae8-977e-7cf84cb59bb1)
parent 89809bef
......@@ -1693,17 +1693,26 @@ class _TabBarState extends State<TabBar> {
TabAlignment.start || TabAlignment.startOffset || TabAlignment.fill => AlignmentDirectional.centerStart,
};
tabBar = CustomPaint(
painter: _DividerPainter(
dividerColor: widget.dividerColor ?? tabBarTheme.dividerColor ?? _defaults.dividerColor!,
dividerHeight: widget.dividerHeight ?? tabBarTheme.dividerHeight ?? _defaults.dividerHeight!,
),
child: Align(
heightFactor: 1.0,
alignment: effectiveAlignment,
child: tabBar,
),
final Color dividerColor = widget.dividerColor ?? tabBarTheme.dividerColor ?? _defaults.dividerColor!;
final double dividerHeight = widget.dividerHeight ?? tabBarTheme.dividerHeight ?? _defaults.dividerHeight!;
final bool showDivider = dividerColor != Colors.transparent && dividerHeight > 0;
tabBar = Align(
heightFactor: 1.0,
widthFactor: showDivider ? null : 1.0,
alignment: effectiveAlignment,
child: tabBar,
);
if (showDivider) {
tabBar = CustomPaint(
painter: _DividerPainter(
dividerColor: widget.dividerColor ?? tabBarTheme.dividerColor ?? _defaults.dividerColor!,
dividerHeight: widget.dividerHeight ?? tabBarTheme.dividerHeight ?? _defaults.dividerHeight!,
),
child: tabBar,
);
}
}
} else if (widget.padding != null) {
tabBar = Padding(
......
......@@ -6636,6 +6636,97 @@ void main() {
expect(unselectedTextStyle.fontStyle, unselectedLabelStyle.fontStyle);
});
// This is a regression test for https://github.com/flutter/flutter/issues/140338.
testWidgets('Material3 - Scrollable TabBar without a divider does not expand to full width', (WidgetTester tester) async {
Widget buildTabBar({
Color? dividerColor,
double? dividerHeight,
TabAlignment? tabAlignment,
}) {
return boilerplate(
child: Center(
child: DefaultTabController(
length: 3,
child: TabBar(
dividerColor: dividerColor,
dividerHeight: dividerHeight,
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 there is a divider and tabAlignment
// is set to startOffset.
await tester.pumpWidget(buildTabBar(tabAlignment: TabAlignment.start));
expect(tester.getSize(find.byType(TabBar)).width, 800.0);
// Test default tab bar width when there is a divider and tabAlignment
// is set to start.
await tester.pumpWidget(buildTabBar(tabAlignment: TabAlignment.startOffset));
expect(tester.getSize(find.byType(TabBar)).width, 800.0);
// Test default tab bar width when there is a divider and tabAlignment
// tabAlignment is set to center.
await tester.pumpWidget(buildTabBar(tabAlignment: TabAlignment.center));
expect(tester.getSize(find.byType(TabBar)).width, 800.0);
// Test default tab bar width when the divider height is set to 0.0
// and tabAlignment is set to startOffset.
await tester.pumpWidget(buildTabBar(
dividerHeight: 0.0,
tabAlignment: TabAlignment.startOffset,
));
expect(tester.getSize(find.byType(TabBar)).width, 359.5);
// Test default tab bar width when the divider height is set to 0.0
// and tabAlignment is set to start.
await tester.pumpWidget(buildTabBar(
dividerHeight: 0.0,
tabAlignment: TabAlignment.start,
));
expect(tester.getSize(find.byType(TabBar)).width, 307.5);
// Test default tab bar width when the divider height is set to 0.0
// and tabAlignment is set to center.
await tester.pumpWidget(buildTabBar(
dividerHeight: 0.0,
tabAlignment: TabAlignment.center,
));
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', () {
// These tests are only relevant for Material 2. Once Material 2
// support is deprecated and the APIs are removed, these tests
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment