Unverified Commit 3ff0beb5 authored by Polina Cherkasova's avatar Polina Cherkasova Committed by GitHub

_TabBarViewState should dispose created instances of PageController. (#134091)

parent 237ddcc3
...@@ -1783,7 +1783,7 @@ class TabBarView extends StatefulWidget { ...@@ -1783,7 +1783,7 @@ class TabBarView extends StatefulWidget {
class _TabBarViewState extends State<TabBarView> { class _TabBarViewState extends State<TabBarView> {
TabController? _controller; TabController? _controller;
late PageController _pageController; PageController? _pageController;
late List<Widget> _childrenWithKey; late List<Widget> _childrenWithKey;
int? _currentIndex; int? _currentIndex;
int _warpUnderwayCount = 0; int _warpUnderwayCount = 0;
...@@ -1825,7 +1825,7 @@ class _TabBarViewState extends State<TabBarView> { ...@@ -1825,7 +1825,7 @@ class _TabBarViewState extends State<TabBarView> {
void _jumpToPage(int page) { void _jumpToPage(int page) {
_warpUnderwayCount += 1; _warpUnderwayCount += 1;
_pageController.jumpToPage(page); _pageController!.jumpToPage(page);
_warpUnderwayCount -= 1; _warpUnderwayCount -= 1;
} }
...@@ -1835,7 +1835,7 @@ class _TabBarViewState extends State<TabBarView> { ...@@ -1835,7 +1835,7 @@ class _TabBarViewState extends State<TabBarView> {
required Curve curve, required Curve curve,
}) async { }) async {
_warpUnderwayCount += 1; _warpUnderwayCount += 1;
await _pageController.animateToPage(page, duration: duration, curve: curve); await _pageController!.animateToPage(page, duration: duration, curve: curve);
_warpUnderwayCount -= 1; _warpUnderwayCount -= 1;
} }
...@@ -1850,6 +1850,8 @@ class _TabBarViewState extends State<TabBarView> { ...@@ -1850,6 +1850,8 @@ class _TabBarViewState extends State<TabBarView> {
super.didChangeDependencies(); super.didChangeDependencies();
_updateTabController(); _updateTabController();
_currentIndex = _controller!.index; _currentIndex = _controller!.index;
// TODO(chunhtai): https://github.com/flutter/flutter/issues/134253
_pageController?.dispose();
_pageController = PageController( _pageController = PageController(
initialPage: _currentIndex!, initialPage: _currentIndex!,
viewportFraction: widget.viewportFraction, viewportFraction: widget.viewportFraction,
...@@ -1877,6 +1879,7 @@ class _TabBarViewState extends State<TabBarView> { ...@@ -1877,6 +1879,7 @@ class _TabBarViewState extends State<TabBarView> {
_controller!.animation!.removeListener(_handleTabControllerAnimationTick); _controller!.animation!.removeListener(_handleTabControllerAnimationTick);
} }
_controller = null; _controller = null;
_pageController?.dispose();
// We don't own the _controller Animation, so it's not disposed here. // We don't own the _controller Animation, so it's not disposed here.
super.dispose(); super.dispose();
} }
...@@ -1897,7 +1900,7 @@ class _TabBarViewState extends State<TabBarView> { ...@@ -1897,7 +1900,7 @@ class _TabBarViewState extends State<TabBarView> {
} }
void _warpToCurrentIndex() { void _warpToCurrentIndex() {
if (!mounted || _pageController.page == _currentIndex!.toDouble()) { if (!mounted || _pageController!.page == _currentIndex!.toDouble()) {
return; return;
} }
...@@ -1957,7 +1960,7 @@ class _TabBarViewState extends State<TabBarView> { ...@@ -1957,7 +1960,7 @@ class _TabBarViewState extends State<TabBarView> {
} }
void _syncControllerOffset() { void _syncControllerOffset() {
_controller!.offset = clampDouble(_pageController.page! - _controller!.index, -1.0, 1.0); _controller!.offset = clampDouble(_pageController!.page! - _controller!.index, -1.0, 1.0);
} }
// Called when the PageView scrolls // Called when the PageView scrolls
...@@ -1975,15 +1978,16 @@ class _TabBarViewState extends State<TabBarView> { ...@@ -1975,15 +1978,16 @@ class _TabBarViewState extends State<TabBarView> {
} }
_scrollUnderwayCount += 1; _scrollUnderwayCount += 1;
final double page = _pageController!.page!;
if (notification is ScrollUpdateNotification && !_controller!.indexIsChanging) { if (notification is ScrollUpdateNotification && !_controller!.indexIsChanging) {
final bool pageChanged = (_pageController.page! - _controller!.index).abs() > 1.0; final bool pageChanged = (page - _controller!.index).abs() > 1.0;
if (pageChanged) { if (pageChanged) {
_controller!.index = _pageController.page!.round(); _controller!.index = page.round();
_currentIndex =_controller!.index; _currentIndex =_controller!.index;
} }
_syncControllerOffset(); _syncControllerOffset();
} else if (notification is ScrollEndNotification) { } else if (notification is ScrollEndNotification) {
_controller!.index = _pageController.page!.round(); _controller!.index = page.round();
_currentIndex = _controller!.index; _currentIndex = _controller!.index;
if (!_controller!.indexIsChanging) { if (!_controller!.indexIsChanging) {
_syncControllerOffset(); _syncControllerOffset();
......
...@@ -84,14 +84,7 @@ void main() { ...@@ -84,14 +84,7 @@ void main() {
await tester.pump(); await tester.pump();
expect(tabController.index, 2); expect(tabController.index, 2);
expect(indicatorColors(tester), const <Color>[kUnselectedColor, kUnselectedColor, kSelectedColor]); expect(indicatorColors(tester), const <Color>[kUnselectedColor, kUnselectedColor, kSelectedColor]);
}, });
// TODO(someone): remove after fixing
// https://github.com/flutter/flutter/issues/133755
leakTrackingTestConfig: const LeakTrackingTestConfig(
notDisposedAllowList: <String, int?>{
'PageController': 1,
},
));
testWidgetsWithLeakTracking('PageSelector responds correctly to TabController.animateTo()', (WidgetTester tester) async { testWidgetsWithLeakTracking('PageSelector responds correctly to TabController.animateTo()', (WidgetTester tester) async {
final TabController tabController = TabController( final TabController tabController = TabController(
...@@ -134,14 +127,7 @@ void main() { ...@@ -134,14 +127,7 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(tabController.index, 2); expect(tabController.index, 2);
expect(indicatorColors(tester), const <Color>[kUnselectedColor, kUnselectedColor, kSelectedColor]); expect(indicatorColors(tester), const <Color>[kUnselectedColor, kUnselectedColor, kSelectedColor]);
}, });
// TODO(someone): remove after fixing
// https://github.com/flutter/flutter/issues/133755
leakTrackingTestConfig: const LeakTrackingTestConfig(
notDisposedAllowList: <String, int?>{
'PageController': 1,
},
));
testWidgetsWithLeakTracking('PageSelector responds correctly to TabBarView drags', (WidgetTester tester) async { testWidgetsWithLeakTracking('PageSelector responds correctly to TabBarView drags', (WidgetTester tester) async {
final TabController tabController = TabController( final TabController tabController = TabController(
...@@ -199,14 +185,7 @@ void main() { ...@@ -199,14 +185,7 @@ void main() {
await tester.fling(find.byType(TabBarView), const Offset(100.0, 0.0), 1000.0); await tester.fling(find.byType(TabBarView), const Offset(100.0, 0.0), 1000.0);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(indicatorColors(tester), const <Color>[kUnselectedColor, kSelectedColor, kUnselectedColor]); expect(indicatorColors(tester), const <Color>[kUnselectedColor, kSelectedColor, kUnselectedColor]);
}, });
// TODO(someone): remove after fixing
// https://github.com/flutter/flutter/issues/133755
leakTrackingTestConfig: const LeakTrackingTestConfig(
notDisposedAllowList: <String, int?>{
'PageController': 1,
},
));
testWidgetsWithLeakTracking('PageSelector indicatorColors', (WidgetTester tester) async { testWidgetsWithLeakTracking('PageSelector indicatorColors', (WidgetTester tester) async {
const Color kRed = Color(0xFFFF0000); const Color kRed = Color(0xFFFF0000);
...@@ -225,14 +204,7 @@ void main() { ...@@ -225,14 +204,7 @@ void main() {
tabController.index = 0; tabController.index = 0;
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(indicatorColors(tester), const <Color>[kBlue, kRed, kRed]); expect(indicatorColors(tester), const <Color>[kBlue, kRed, kRed]);
}, });
// TODO(someone): remove after fixing
// https://github.com/flutter/flutter/issues/133755
leakTrackingTestConfig: const LeakTrackingTestConfig(
notDisposedAllowList: <String, int?>{
'PageController': 1,
},
));
testWidgets('PageSelector indicatorSize', (WidgetTester tester) async { testWidgets('PageSelector indicatorSize', (WidgetTester tester) async {
final TabController tabController = TabController( final TabController tabController = TabController(
...@@ -299,12 +271,5 @@ void main() { ...@@ -299,12 +271,5 @@ void main() {
for (final TabPageSelectorIndicator indicator in indicators) { for (final TabPageSelectorIndicator indicator in indicators) {
expect(indicator.borderStyle, BorderStyle.solid); expect(indicator.borderStyle, BorderStyle.solid);
} }
}, });
// TODO(someone): remove after fixing
// https://github.com/flutter/flutter/issues/133755
leakTrackingTestConfig: const LeakTrackingTestConfig(
notDisposedAllowList: <String, int?>{
'PageController': 1,
},
));
} }
...@@ -1834,14 +1834,7 @@ void main() { ...@@ -1834,14 +1834,7 @@ void main() {
); );
scrollController.dispose(); scrollController.dispose();
}, });
// TODO(someone): remove after fixing
// https://github.com/flutter/flutter/issues/133755
leakTrackingTestConfig: const LeakTrackingTestConfig(
notDisposedAllowList: <String, int?>{
'PageController': 2,
},
));
testWidgetsWithLeakTracking('Scrollbar scrollOrientation works correctly', (WidgetTester tester) async { testWidgetsWithLeakTracking('Scrollbar scrollOrientation works correctly', (WidgetTester tester) async {
final ScrollController scrollController = ScrollController(); final ScrollController scrollController = ScrollController();
......
...@@ -81,12 +81,5 @@ void main() { ...@@ -81,12 +81,5 @@ void main() {
// should not crash. // should not crash.
await tester.tap(find.text('Tab 2')); await tester.tap(find.text('Tab 2'));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
}, });
// TODO(someone): remove after fixing
// https://github.com/flutter/flutter/issues/133755
leakTrackingTestConfig: const LeakTrackingTestConfig(
notDisposedAllowList: <String, int?>{
'PageController': 1,
},
));
} }
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