Skip to content

Commit 3ff0beb

Browse files
authored
_TabBarViewState should dispose created instances of PageController. (#134091)
1 parent 237ddcc commit 3ff0beb

File tree

4 files changed

+19
-64
lines changed

4 files changed

+19
-64
lines changed

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

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1783,7 +1783,7 @@ class TabBarView extends StatefulWidget {
17831783

17841784
class _TabBarViewState extends State<TabBarView> {
17851785
TabController? _controller;
1786-
late PageController _pageController;
1786+
PageController? _pageController;
17871787
late List<Widget> _childrenWithKey;
17881788
int? _currentIndex;
17891789
int _warpUnderwayCount = 0;
@@ -1825,7 +1825,7 @@ class _TabBarViewState extends State<TabBarView> {
18251825

18261826
void _jumpToPage(int page) {
18271827
_warpUnderwayCount += 1;
1828-
_pageController.jumpToPage(page);
1828+
_pageController!.jumpToPage(page);
18291829
_warpUnderwayCount -= 1;
18301830
}
18311831

@@ -1835,7 +1835,7 @@ class _TabBarViewState extends State<TabBarView> {
18351835
required Curve curve,
18361836
}) async {
18371837
_warpUnderwayCount += 1;
1838-
await _pageController.animateToPage(page, duration: duration, curve: curve);
1838+
await _pageController!.animateToPage(page, duration: duration, curve: curve);
18391839
_warpUnderwayCount -= 1;
18401840
}
18411841

@@ -1850,6 +1850,8 @@ class _TabBarViewState extends State<TabBarView> {
18501850
super.didChangeDependencies();
18511851
_updateTabController();
18521852
_currentIndex = _controller!.index;
1853+
// TODO(chunhtai): https://github.com/flutter/flutter/issues/134253
1854+
_pageController?.dispose();
18531855
_pageController = PageController(
18541856
initialPage: _currentIndex!,
18551857
viewportFraction: widget.viewportFraction,
@@ -1877,6 +1879,7 @@ class _TabBarViewState extends State<TabBarView> {
18771879
_controller!.animation!.removeListener(_handleTabControllerAnimationTick);
18781880
}
18791881
_controller = null;
1882+
_pageController?.dispose();
18801883
// We don't own the _controller Animation, so it's not disposed here.
18811884
super.dispose();
18821885
}
@@ -1897,7 +1900,7 @@ class _TabBarViewState extends State<TabBarView> {
18971900
}
18981901

18991902
void _warpToCurrentIndex() {
1900-
if (!mounted || _pageController.page == _currentIndex!.toDouble()) {
1903+
if (!mounted || _pageController!.page == _currentIndex!.toDouble()) {
19011904
return;
19021905
}
19031906

@@ -1957,7 +1960,7 @@ class _TabBarViewState extends State<TabBarView> {
19571960
}
19581961

19591962
void _syncControllerOffset() {
1960-
_controller!.offset = clampDouble(_pageController.page! - _controller!.index, -1.0, 1.0);
1963+
_controller!.offset = clampDouble(_pageController!.page! - _controller!.index, -1.0, 1.0);
19611964
}
19621965

19631966
// Called when the PageView scrolls
@@ -1975,15 +1978,16 @@ class _TabBarViewState extends State<TabBarView> {
19751978
}
19761979

19771980
_scrollUnderwayCount += 1;
1981+
final double page = _pageController!.page!;
19781982
if (notification is ScrollUpdateNotification && !_controller!.indexIsChanging) {
1979-
final bool pageChanged = (_pageController.page! - _controller!.index).abs() > 1.0;
1983+
final bool pageChanged = (page - _controller!.index).abs() > 1.0;
19801984
if (pageChanged) {
1981-
_controller!.index = _pageController.page!.round();
1985+
_controller!.index = page.round();
19821986
_currentIndex =_controller!.index;
19831987
}
19841988
_syncControllerOffset();
19851989
} else if (notification is ScrollEndNotification) {
1986-
_controller!.index = _pageController.page!.round();
1990+
_controller!.index = page.round();
19871991
_currentIndex = _controller!.index;
19881992
if (!_controller!.indexIsChanging) {
19891993
_syncControllerOffset();

packages/flutter/test/material/page_selector_test.dart

Lines changed: 5 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,7 @@ void main() {
8484
await tester.pump();
8585
expect(tabController.index, 2);
8686
expect(indicatorColors(tester), const <Color>[kUnselectedColor, kUnselectedColor, kSelectedColor]);
87-
},
88-
// TODO(someone): remove after fixing
89-
// https://github.com/flutter/flutter/issues/133755
90-
leakTrackingTestConfig: const LeakTrackingTestConfig(
91-
notDisposedAllowList: <String, int?>{
92-
'PageController': 1,
93-
},
94-
));
87+
});
9588

9689
testWidgetsWithLeakTracking('PageSelector responds correctly to TabController.animateTo()', (WidgetTester tester) async {
9790
final TabController tabController = TabController(
@@ -134,14 +127,7 @@ void main() {
134127
await tester.pumpAndSettle();
135128
expect(tabController.index, 2);
136129
expect(indicatorColors(tester), const <Color>[kUnselectedColor, kUnselectedColor, kSelectedColor]);
137-
},
138-
// TODO(someone): remove after fixing
139-
// https://github.com/flutter/flutter/issues/133755
140-
leakTrackingTestConfig: const LeakTrackingTestConfig(
141-
notDisposedAllowList: <String, int?>{
142-
'PageController': 1,
143-
},
144-
));
130+
});
145131

146132
testWidgetsWithLeakTracking('PageSelector responds correctly to TabBarView drags', (WidgetTester tester) async {
147133
final TabController tabController = TabController(
@@ -199,14 +185,7 @@ void main() {
199185
await tester.fling(find.byType(TabBarView), const Offset(100.0, 0.0), 1000.0);
200186
await tester.pumpAndSettle();
201187
expect(indicatorColors(tester), const <Color>[kUnselectedColor, kSelectedColor, kUnselectedColor]);
202-
},
203-
// TODO(someone): remove after fixing
204-
// https://github.com/flutter/flutter/issues/133755
205-
leakTrackingTestConfig: const LeakTrackingTestConfig(
206-
notDisposedAllowList: <String, int?>{
207-
'PageController': 1,
208-
},
209-
));
188+
});
210189

211190
testWidgetsWithLeakTracking('PageSelector indicatorColors', (WidgetTester tester) async {
212191
const Color kRed = Color(0xFFFF0000);
@@ -225,14 +204,7 @@ void main() {
225204
tabController.index = 0;
226205
await tester.pumpAndSettle();
227206
expect(indicatorColors(tester), const <Color>[kBlue, kRed, kRed]);
228-
},
229-
// TODO(someone): remove after fixing
230-
// https://github.com/flutter/flutter/issues/133755
231-
leakTrackingTestConfig: const LeakTrackingTestConfig(
232-
notDisposedAllowList: <String, int?>{
233-
'PageController': 1,
234-
},
235-
));
207+
});
236208

237209
testWidgets('PageSelector indicatorSize', (WidgetTester tester) async {
238210
final TabController tabController = TabController(
@@ -299,12 +271,5 @@ void main() {
299271
for (final TabPageSelectorIndicator indicator in indicators) {
300272
expect(indicator.borderStyle, BorderStyle.solid);
301273
}
302-
},
303-
// TODO(someone): remove after fixing
304-
// https://github.com/flutter/flutter/issues/133755
305-
leakTrackingTestConfig: const LeakTrackingTestConfig(
306-
notDisposedAllowList: <String, int?>{
307-
'PageController': 1,
308-
},
309-
));
274+
});
310275
}

packages/flutter/test/material/scrollbar_test.dart

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1834,14 +1834,7 @@ void main() {
18341834
);
18351835

18361836
scrollController.dispose();
1837-
},
1838-
// TODO(someone): remove after fixing
1839-
// https://github.com/flutter/flutter/issues/133755
1840-
leakTrackingTestConfig: const LeakTrackingTestConfig(
1841-
notDisposedAllowList: <String, int?>{
1842-
'PageController': 2,
1843-
},
1844-
));
1837+
});
18451838

18461839
testWidgetsWithLeakTracking('Scrollbar scrollOrientation works correctly', (WidgetTester tester) async {
18471840
final ScrollController scrollController = ScrollController();

packages/flutter/test/material/tabbed_scrollview_warp_test.dart

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,5 @@ void main() {
8181
// should not crash.
8282
await tester.tap(find.text('Tab 2'));
8383
await tester.pumpAndSettle();
84-
},
85-
// TODO(someone): remove after fixing
86-
// https://github.com/flutter/flutter/issues/133755
87-
leakTrackingTestConfig: const LeakTrackingTestConfig(
88-
notDisposedAllowList: <String, int?>{
89-
'PageController': 1,
90-
},
91-
));
84+
});
9285
}

0 commit comments

Comments
 (0)