diff --git a/packages/flutter/lib/src/widgets/page_view.dart b/packages/flutter/lib/src/widgets/page_view.dart index 1c69aeeeafe..d1ea02483fb 100644 --- a/packages/flutter/lib/src/widgets/page_view.dart +++ b/packages/flutter/lib/src/widgets/page_view.dart @@ -200,6 +200,11 @@ class PageController extends ScrollController { return Future.value(); } + if (!position.hasViewportDimension) { + position._pageToUseOnStartup = page.toDouble(); + return Future.value(); + } + return position.animateTo( position.getPixelsFromPage(page.toDouble()), duration: duration, @@ -218,6 +223,11 @@ class PageController extends ScrollController { return; } + if (!position.hasViewportDimension) { + position._pageToUseOnStartup = page.toDouble(); + return; + } + position.jumpTo(position.getPixelsFromPage(page.toDouble())); } diff --git a/packages/flutter/test/widgets/page_view_test.dart b/packages/flutter/test/widgets/page_view_test.dart index 78e6fd8cbf2..17ba79c7997 100644 --- a/packages/flutter/test/widgets/page_view_test.dart +++ b/packages/flutter/test/widgets/page_view_test.dart @@ -1413,4 +1413,62 @@ void main() { expect(find.text('null'), findsNothing); expect(currentPage, 'not empty'); }); + + testWidgets('Does not crash when calling jumpToPage before layout', (WidgetTester tester) async { + // Regression test for https://github.com/flutter/flutter/issues/86222. + final PageController controller = PageController(); + addTearDown(controller.dispose); + + await tester.pumpWidget(MaterialApp( + home: Scaffold( + body: Navigator( + onDidRemovePage: (Page page) {}, + pages: >[ + MaterialPage(child: Scaffold( + body: PageView( + controller: controller, + children: const [ + Scaffold(body: Text('One')), + Scaffold(body: Text('Two')), + ], + ), + )), + const MaterialPage(child: Scaffold()), + ], + ), + ) + )); + + controller.jumpToPage(1); + expect(tester.takeException(), null); + }); + + testWidgets('Does not crash when calling animateToPage before layout', (WidgetTester tester) async { + // Regression test for https://github.com/flutter/flutter/issues/86222. + final PageController controller = PageController(); + addTearDown(controller.dispose); + + await tester.pumpWidget(MaterialApp( + home: Scaffold( + body: Navigator( + onDidRemovePage: (Page page) {}, + pages: >[ + MaterialPage(child: Scaffold( + body: PageView( + controller: controller, + children: const [ + Scaffold(body: Text('One')), + Scaffold(body: Text('Two')), + ], + ), + )), + const MaterialPage(child: Scaffold()), + ], + ), + ) + )); + + controller.animateToPage(1, duration: const Duration(milliseconds: 50), curve: Curves.bounceIn); + expect(tester.takeException(), null); + }); }