Skip to content

Commit f4f68df

Browse files
authored
Make the page-view remembering logic actually work. (flutter#9905)
It wasn't tested, which is why it didn't work before.
1 parent 3bd2ecb commit f4f68df

File tree

3 files changed

+68
-3
lines changed

3 files changed

+68
-3
lines changed

packages/flutter/lib/src/widgets/page_view.dart

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,9 @@ class _PagePosition extends ScrollPositionWithSingleContext {
154154
this.initialPage: 0,
155155
double viewportFraction: 1.0,
156156
ScrollPosition oldPosition,
157-
}) : _viewportFraction = viewportFraction, super(
157+
}) : _viewportFraction = viewportFraction,
158+
_pageToUseOnStartup = initialPage.toDouble(),
159+
super(
158160
physics: physics,
159161
context: context,
160162
initialPixels: null,
@@ -166,6 +168,7 @@ class _PagePosition extends ScrollPositionWithSingleContext {
166168
}
167169

168170
final int initialPage;
171+
double _pageToUseOnStartup;
169172

170173
double get viewportFraction => _viewportFraction;
171174
double _viewportFraction;
@@ -198,7 +201,7 @@ class _PagePosition extends ScrollPositionWithSingleContext {
198201
if (pixels == null) {
199202
final double value = PageStorage.of(context.storageContext)?.readState(context.storageContext);
200203
if (value != null)
201-
correctPixels(getPixelsFromPage(value));
204+
_pageToUseOnStartup = value;
202205
}
203206
}
204207

@@ -207,7 +210,7 @@ class _PagePosition extends ScrollPositionWithSingleContext {
207210
final double oldViewportDimensions = this.viewportDimension;
208211
final bool result = super.applyViewportDimension(viewportDimension);
209212
final double oldPixels = pixels;
210-
final double page = (oldPixels == null || oldViewportDimensions == 0.0) ? initialPage.toDouble() : getPageFromPixels(oldPixels, oldViewportDimensions);
213+
final double page = (oldPixels == null || oldViewportDimensions == 0.0) ? _pageToUseOnStartup : getPageFromPixels(oldPixels, oldViewportDimensions);
211214
final double newPixels = getPixelsFromPage(page);
212215
if (newPixels != oldPixels) {
213216
correctPixels(newPixels);

packages/flutter/lib/src/widgets/scroll_position.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,9 @@ abstract class ScrollPosition extends ViewportOffset with ScrollMetrics {
300300
/// The default implementation reads the value from the nearest [PageStorage]
301301
/// found from the [context]'s [ScrollContext.storageContext] property, and
302302
/// sets it using [correctPixels], if [pixels] is still null.
303+
///
304+
/// This method is called from the constructor, so layout has not yet
305+
/// occurred, and the viewport dimensions aren't yet known when it is called.
303306
@protected
304307
void restoreScrollOffset() {
305308
if (pixels == null) {

packages/flutter/test/widgets/page_view_test.dart

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,4 +398,63 @@ void main() {
398398
await tester.pump();
399399
expect(changeIndex, 0);
400400
});
401+
402+
testWidgets('PageView can restore page',
403+
(WidgetTester tester) async {
404+
final PageController controller = new PageController();
405+
final PageStorageBucket bucket = new PageStorageBucket();
406+
await tester.pumpWidget(
407+
new PageStorage(
408+
bucket: bucket,
409+
child: new PageView(
410+
controller: controller,
411+
children: <Widget>[
412+
const Placeholder(),
413+
const Placeholder(),
414+
const Placeholder(),
415+
],
416+
),
417+
),
418+
);
419+
expect(controller.page, 0);
420+
controller.jumpToPage(2);
421+
expect(await tester.pumpAndSettle(const Duration(minutes: 1)), 1);
422+
expect(controller.page, 2);
423+
await tester.pumpWidget(
424+
new PageStorage(
425+
bucket: bucket,
426+
child: new Container(),
427+
),
428+
);
429+
expect(() => controller.page, throwsAssertionError);
430+
await tester.pumpWidget(
431+
new PageStorage(
432+
bucket: bucket,
433+
child: new PageView(
434+
controller: controller,
435+
children: <Widget>[
436+
const Placeholder(),
437+
const Placeholder(),
438+
const Placeholder(),
439+
],
440+
),
441+
),
442+
);
443+
expect(controller.page, 2);
444+
await tester.pumpWidget(
445+
new PageStorage(
446+
bucket: bucket,
447+
child: new PageView(
448+
key: const Key('Check it again against your list and see consistency!'),
449+
controller: controller,
450+
children: <Widget>[
451+
const Placeholder(),
452+
const Placeholder(),
453+
const Placeholder(),
454+
],
455+
),
456+
),
457+
);
458+
expect(controller.page, 0);
459+
});
401460
}

0 commit comments

Comments
 (0)