Skip to content

Commit 0d90014

Browse files
authored
_TabBarViewState should not recreate page controller (#135500)
## Description This PR replaces the unconditional instantiation of `PageController` in `_TabBarViewState.didChangeDependencies` as suggested in flutter/flutter#134091 (comment). ## Related Issue Fixes flutter/flutter#134253. ## Tests Adds 1 test.
1 parent da0cd69 commit 0d90014

File tree

2 files changed

+46
-6
lines changed

2 files changed

+46
-6
lines changed

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

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1851,12 +1851,14 @@ class _TabBarViewState extends State<TabBarView> {
18511851
super.didChangeDependencies();
18521852
_updateTabController();
18531853
_currentIndex = _controller!.index;
1854-
// TODO(chunhtai): https://github.com/flutter/flutter/issues/134253
1855-
_pageController?.dispose();
1856-
_pageController = PageController(
1857-
initialPage: _currentIndex!,
1858-
viewportFraction: widget.viewportFraction,
1859-
);
1854+
if (_pageController == null) {
1855+
_pageController = PageController(
1856+
initialPage: _currentIndex!,
1857+
viewportFraction: widget.viewportFraction,
1858+
);
1859+
} else {
1860+
_pageController!.jumpToPage(_currentIndex!);
1861+
}
18601862
}
18611863

18621864
@override

packages/flutter/test/material/tabs_test.dart

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4186,6 +4186,44 @@ void main() {
41864186
expect(tester.getCenter(find.byKey(lastTabKey)).dx, equals(750.0));
41874187
});
41884188

4189+
testWidgets('DefaultTabController changes does not recreate PageController', (WidgetTester tester) async {
4190+
// This is a regression test for https://github.com/flutter/flutter/issues/134253.
4191+
Widget buildFrame(int length) {
4192+
return boilerplate(
4193+
child: DefaultTabController(
4194+
length: length,
4195+
initialIndex: length - 1,
4196+
child: TabBarView(
4197+
physics: const TestScrollPhysics(),
4198+
children: List<Widget>.generate(
4199+
length,
4200+
(int index) {
4201+
return Center(child: Text('Page $index'));
4202+
},
4203+
),
4204+
),
4205+
),
4206+
);
4207+
}
4208+
4209+
await tester.pumpWidget(buildFrame(15));
4210+
PageView pageView = tester.widget(find.byType(PageView));
4211+
final PageController pageController1 = pageView.controller;
4212+
TabController tabController = DefaultTabController.of(tester.element(find.text('Page 14')));
4213+
expect(tabController.index, 14);
4214+
expect(pageController1.page, 14);
4215+
4216+
// Rebuild with a new default tab controller with more tabs.
4217+
await tester.pumpWidget(buildFrame(10));
4218+
pageView = tester.widget(find.byType(PageView));
4219+
final PageController pageController2 = pageView.controller;
4220+
tabController = DefaultTabController.of(tester.element(find.text('Page 9')));
4221+
expect(tabController.index, 9);
4222+
expect(pageController2.page, 9);
4223+
4224+
expect(pageController1, equals(pageController2));
4225+
});
4226+
41894227
testWidgets('Do not throw when switching between a scrollable TabBar and a non-scrollable TabBar', (WidgetTester tester) async {
41904228
// This is a regression test for https://github.com/flutter/flutter/issues/120649
41914229
final TabController controller1 = _tabController(

0 commit comments

Comments
 (0)