Commit 7cde72fe authored by Adam Barth's avatar Adam Barth Committed by GitHub

Make remember_scroll_position_test.dart pass (#8074)

We've decided not to store the scroll position in PageStorage because
routes now maintainState by default.

Fixes #8051
parent cff7dc54
...@@ -124,7 +124,7 @@ abstract class ViewportOffset extends ChangeNotifier { ...@@ -124,7 +124,7 @@ abstract class ViewportOffset extends ChangeNotifier {
@mustCallSuper @mustCallSuper
void debugFillDescription(List<String> description) { void debugFillDescription(List<String> description) {
description.add('offset: ${pixels.toStringAsFixed(1)}'); description.add('offset: ${pixels?.toStringAsFixed(1)}');
} }
} }
......
...@@ -19,13 +19,15 @@ import 'sliver.dart'; ...@@ -19,13 +19,15 @@ import 'sliver.dart';
class PageController extends ScrollController { class PageController extends ScrollController {
PageController({ PageController({
this.initialPage: 0, this.initialPage: 0,
}); }) {
assert(initialPage != null);
}
final int initialPage; final int initialPage;
double get page { double get page {
final ScrollPosition position = this.position; final _PagePosition position = this.position;
return position.pixels / position.viewportDimension; return position.page;
} }
Future<Null> animateToPage(int page, { Future<Null> animateToPage(int page, {
...@@ -71,10 +73,14 @@ class _PagePosition extends ScrollPosition { ...@@ -71,10 +73,14 @@ class _PagePosition extends ScrollPosition {
state: state, state: state,
initialPixels: null, initialPixels: null,
oldPosition: oldPosition, oldPosition: oldPosition,
); ) {
assert(initialPage != null);
}
final int initialPage; final int initialPage;
double get page => pixels / viewportDimension;
@override @override
bool applyViewportDimension(double viewportDimension) { bool applyViewportDimension(double viewportDimension) {
final double oldViewportDimensions = this.viewportDimension; final double oldViewportDimensions = this.viewportDimension;
......
...@@ -12,7 +12,9 @@ import 'scroll_position.dart'; ...@@ -12,7 +12,9 @@ import 'scroll_position.dart';
class ScrollController { class ScrollController {
ScrollController({ ScrollController({
this.initialScrollOffset: 0.0, this.initialScrollOffset: 0.0,
}); }) {
assert(initialScrollOffset != null);
}
/// The initial value to use for [offset]. /// The initial value to use for [offset].
/// ///
......
...@@ -275,7 +275,7 @@ class ScrollPosition extends ViewportOffset { ...@@ -275,7 +275,7 @@ class ScrollPosition extends ViewportOffset {
} }
return true; return true;
}); });
double oldPixels = _pixels; final double oldPixels = _pixels;
_pixels = value - overScroll; _pixels = value - overScroll;
if (_pixels != oldPixels) { if (_pixels != oldPixels) {
notifyListeners(); notifyListeners();
......
...@@ -13,117 +13,107 @@ class ThePositiveNumbers extends StatelessWidget { ...@@ -13,117 +13,107 @@ class ThePositiveNumbers extends StatelessWidget {
final int from; final int from;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return new ScrollableLazyList( return new ListView.builder(
itemExtent: 100.0, itemExtent: 100.0,
itemBuilder: (BuildContext context, int start, int count) { itemBuilder: (BuildContext context, int index) {
List<Widget> result = new List<Widget>(); return new Text('${index + from}', key: new ValueKey<int>(index));
for (int index = start; index < start + count; index += 1)
result.add(new Text('${index + from}', key: new ValueKey<int>(index)));
return result;
} }
); );
} }
} }
Future<Null> performTest(WidgetTester tester, bool maintainState) async { Future<Null> performTest(WidgetTester tester) async {
GlobalKey<NavigatorState> navigatorKey = new GlobalKey<NavigatorState>();
await tester.pumpWidget(new Navigator(
key: navigatorKey,
onGenerateRoute: (RouteSettings settings) {
if (settings.name == '/') {
return new MaterialPageRoute<Null>(
settings: settings,
builder: (_) => new Container(child: new ThePositiveNumbers(from: 0)),
maintainState: maintainState,
);
} else if (settings.name == '/second') {
return new MaterialPageRoute<Null>(
settings: settings,
builder: (_) => new Container(child: new ThePositiveNumbers(from: 10000)),
maintainState: maintainState,
);
}
return null;
}
));
// we're 600 pixels high, each item is 100 pixels high, scroll position is
// zero, so we should have exactly 6 items, 0..5.
expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsOneWidget);
expect(find.text('2'), findsOneWidget);
expect(find.text('3'), findsOneWidget);
expect(find.text('4'), findsOneWidget);
expect(find.text('5'), findsOneWidget);
expect(find.text('6'), findsNothing);
expect(find.text('10'), findsNothing);
expect(find.text('100'), findsNothing);
Completer<Null> completer = new Completer<Null>();
tester.state<ScrollableState>(find.byType(Scrollable)).scrollTo(1000.0).whenComplete(completer.complete);
expect(completer.isCompleted, isFalse);
await tester.pump(const Duration(seconds: 1));
expect(completer.isCompleted, isTrue);
// we're 600 pixels high, each item is 100 pixels high, scroll position is
// 1000, so we should have exactly 6 items, 10..15.
expect(find.text('0'), findsNothing);
expect(find.text('8'), findsNothing);
expect(find.text('9'), findsNothing);
expect(find.text('10'), findsOneWidget);
expect(find.text('11'), findsOneWidget);
expect(find.text('12'), findsOneWidget);
expect(find.text('13'), findsOneWidget);
expect(find.text('14'), findsOneWidget);
expect(find.text('15'), findsOneWidget);
expect(find.text('16'), findsNothing);
expect(find.text('100'), findsNothing);
navigatorKey.currentState.pushNamed('/second');
await tester.pump(); // navigating always takes two frames, one to start...
await tester.pump(const Duration(seconds: 1)); // ...and one to end the transition
// the second list is now visible, starting at 10000
expect(find.text('10000'), findsOneWidget);
expect(find.text('10001'), findsOneWidget);
expect(find.text('10002'), findsOneWidget);
expect(find.text('10003'), findsOneWidget);
expect(find.text('10004'), findsOneWidget);
expect(find.text('10005'), findsOneWidget);
expect(find.text('10006'), findsNothing);
expect(find.text('10010'), findsNothing);
expect(find.text('10100'), findsNothing);
navigatorKey.currentState.pop();
await tester.pump(); // again, navigating always takes two frames
// Ensure we don't clamp the scroll offset even during the navigation.
// https://github.com/flutter/flutter/issues/4883
LazyListViewport viewport = tester.firstWidget(find.byType(LazyListViewport));
expect(viewport.scrollOffset, equals(1000.0));
await tester.pump(const Duration(seconds: 1));
// we're 600 pixels high, each item is 100 pixels high, scroll position is
// 1000, so we should have exactly 6 items, 10..15.
expect(find.text('0'), findsNothing);
expect(find.text('8'), findsNothing);
expect(find.text('9'), findsNothing);
expect(find.text('10'), findsOneWidget);
expect(find.text('11'), findsOneWidget);
expect(find.text('12'), findsOneWidget);
expect(find.text('13'), findsOneWidget);
expect(find.text('14'), findsOneWidget);
expect(find.text('15'), findsOneWidget);
expect(find.text('16'), findsNothing);
expect(find.text('100'), findsNothing);
} }
void main() { void main() {
testWidgets('whether we remember our scroll position', (WidgetTester tester) async { testWidgets('whether we remember our scroll position', (WidgetTester tester) async {
await performTest(tester, true); GlobalKey<NavigatorState> navigatorKey = new GlobalKey<NavigatorState>();
await performTest(tester, false); await tester.pumpWidget(new Navigator(
key: navigatorKey,
onGenerateRoute: (RouteSettings settings) {
if (settings.name == '/') {
return new MaterialPageRoute<Null>(
settings: settings,
builder: (_) => new Container(child: new ThePositiveNumbers(from: 0)),
);
} else if (settings.name == '/second') {
return new MaterialPageRoute<Null>(
settings: settings,
builder: (_) => new Container(child: new ThePositiveNumbers(from: 10000)),
);
}
return null;
}
));
// we're 600 pixels high, each item is 100 pixels high, scroll position is
// zero, so we should have exactly 6 items, 0..5.
expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsOneWidget);
expect(find.text('2'), findsOneWidget);
expect(find.text('3'), findsOneWidget);
expect(find.text('4'), findsOneWidget);
expect(find.text('5'), findsOneWidget);
expect(find.text('6'), findsNothing);
expect(find.text('10'), findsNothing);
expect(find.text('100'), findsNothing);
tester.state<Scrollable2State>(find.byType(Scrollable2)).position.jumpTo(1000.0);
await tester.pump(const Duration(seconds: 1));
// we're 600 pixels high, each item is 100 pixels high, scroll position is
// 1000, so we should have exactly 6 items, 10..15.
expect(find.text('0'), findsNothing);
expect(find.text('8'), findsNothing);
expect(find.text('9'), findsNothing);
expect(find.text('10'), findsOneWidget);
expect(find.text('11'), findsOneWidget);
expect(find.text('12'), findsOneWidget);
expect(find.text('13'), findsOneWidget);
expect(find.text('14'), findsOneWidget);
expect(find.text('15'), findsOneWidget);
expect(find.text('16'), findsNothing);
expect(find.text('100'), findsNothing);
navigatorKey.currentState.pushNamed('/second');
await tester.pump(); // navigating always takes two frames, one to start...
await tester.pump(const Duration(seconds: 1)); // ...and one to end the transition
// the second list is now visible, starting at 10000
expect(find.text('10000'), findsOneWidget);
expect(find.text('10001'), findsOneWidget);
expect(find.text('10002'), findsOneWidget);
expect(find.text('10003'), findsOneWidget);
expect(find.text('10004'), findsOneWidget);
expect(find.text('10005'), findsOneWidget);
expect(find.text('10006'), findsNothing);
expect(find.text('10010'), findsNothing);
expect(find.text('10100'), findsNothing);
navigatorKey.currentState.pop();
await tester.pump(); // again, navigating always takes two frames
// Ensure we don't clamp the scroll offset even during the navigation.
// https://github.com/flutter/flutter/issues/4883
Scrollable2State state = tester.state(find.byType(Scrollable2).first);
expect(state.position.pixels, equals(1000.0));
await tester.pump(const Duration(seconds: 1));
// we're 600 pixels high, each item is 100 pixels high, scroll position is
// 1000, so we should have exactly 6 items, 10..15.
expect(find.text('0'), findsNothing);
expect(find.text('8'), findsNothing);
expect(find.text('9'), findsNothing);
expect(find.text('10'), findsOneWidget);
expect(find.text('11'), findsOneWidget);
expect(find.text('12'), findsOneWidget);
expect(find.text('13'), findsOneWidget);
expect(find.text('14'), findsOneWidget);
expect(find.text('15'), findsOneWidget);
expect(find.text('16'), findsNothing);
expect(find.text('100'), findsNothing);
}); });
} }
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