Skip to content

Commit 541a8bf

Browse files
authored
Fix switching from scrollable and non-scrollable tab bars throws (flutter#120771)
Co-authored-by: Bruno Leroux <[email protected]>
1 parent 7865713 commit 541a8bf

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1142,7 +1142,7 @@ class _TabBarState extends State<TabBar> {
11421142
_updateTabController();
11431143
_initIndicatorPainter();
11441144
// Adjust scroll position.
1145-
if (_scrollController != null) {
1145+
if (_scrollController != null && _scrollController!.hasClients) {
11461146
final ScrollPosition position = _scrollController!.position;
11471147
if (position is _TabBarScrollPosition) {
11481148
position.markNeedsPixelsCorrection();

packages/flutter/test/material/tabs_test.dart

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3568,6 +3568,46 @@ void main() {
35683568
expect(tester.getCenter(find.byKey(lastTabKey)).dx, equals(750.0));
35693569
});
35703570

3571+
testWidgets('Do not throw when switching beetween a scrollable TabBar and a non-scrollable TabBar', (WidgetTester tester) async {
3572+
// This is a regression test for https://github.com/flutter/flutter/issues/120649
3573+
final TabController controller1 = TabController(
3574+
vsync: const TestVSync(),
3575+
length: 2,
3576+
);
3577+
final TabController controller2 = TabController(
3578+
vsync: const TestVSync(),
3579+
length: 2,
3580+
);
3581+
3582+
Widget buildFrame(TabController controller, bool isScrollable) {
3583+
return boilerplate(
3584+
child: Container(
3585+
alignment: Alignment.topLeft,
3586+
child: TabBar(
3587+
controller: controller,
3588+
isScrollable: isScrollable,
3589+
tabs: const <Tab>[
3590+
Tab(text: 'LEFT'),
3591+
Tab(text: 'RIGHT'),
3592+
],
3593+
),
3594+
),
3595+
);
3596+
}
3597+
3598+
// Show both controllers once.
3599+
await tester.pumpWidget(buildFrame(controller1, false));
3600+
await tester.pumpWidget(buildFrame(controller2, true));
3601+
3602+
// Switch back to the first controller.
3603+
await tester.pumpWidget(buildFrame(controller1, false));
3604+
expect(tester.takeException(), null);
3605+
3606+
// Switch back to the second controller.
3607+
await tester.pumpWidget(buildFrame(controller2, true));
3608+
expect(tester.takeException(), null);
3609+
});
3610+
35713611
testWidgets('Default tab indicator color is white', (WidgetTester tester) async {
35723612
// Regression test for https://github.com/flutter/flutter/issues/15958
35733613
final List<String> tabs = <String>['LEFT', 'RIGHT'];

0 commit comments

Comments
 (0)