Unverified Commit 65f232fd authored by Michael Goderbauer's avatar Michael Goderbauer Committed by GitHub

Add restorationId to Material/CupertinoPage (#78450)

parent fd37a50f
......@@ -401,10 +401,11 @@ class CupertinoPage<T> extends Page<T> {
LocalKey? key,
String? name,
Object? arguments,
String? restorationId,
}) : assert(child != null),
assert(maintainState != null),
assert(fullscreenDialog != null),
super(key: key, name: name, arguments: arguments);
super(key: key, name: name, arguments: arguments, restorationId: restorationId);
/// The content to be shown in the [Route] created by this page.
final Widget child;
......
......@@ -156,10 +156,11 @@ class MaterialPage<T> extends Page<T> {
LocalKey? key,
String? name,
Object? arguments,
String? restorationId,
}) : assert(child != null),
assert(maintainState != null),
assert(fullscreenDialog != null),
super(key: key, name: name, arguments: arguments);
super(key: key, name: name, arguments: arguments, restorationId: restorationId);
/// The content to be shown in the [Route] created by this page.
final Widget child;
......
......@@ -475,6 +475,68 @@ void main() {
expect(find.text('subpage'), findsOneWidget);
expect(find.text('home'), findsOneWidget);
});
testWidgets('CupertinoPage restores its state', (WidgetTester tester) async {
await tester.pumpWidget(
RootRestorationScope(
restorationId: 'root',
child: MediaQuery(
data: const MediaQueryData(),
child: Directionality(
textDirection: TextDirection.ltr,
child: Navigator(
onPopPage: (Route<dynamic> route, dynamic result) { return false; },
pages: const <Page<Object?>>[
CupertinoPage<void>(
restorationId: 'p1',
child: TestRestorableWidget(restorationId: 'p1'),
),
],
restorationScopeId: 'nav',
onGenerateRoute: (RouteSettings settings) {
return CupertinoPageRoute<void>(
settings: settings,
builder: (BuildContext context) {
return TestRestorableWidget(restorationId: settings.name!);
},
);
},
),
),
),
),
);
expect(find.text('p1'), findsOneWidget);
expect(find.text('count: 0'), findsOneWidget);
await tester.tap(find.text('increment'));
await tester.pump();
expect(find.text('count: 1'), findsOneWidget);
tester.state<NavigatorState>(find.byType(Navigator)).restorablePushNamed('p2');
await tester.pumpAndSettle();
expect(find.text('p1'), findsNothing);
expect(find.text('p2'), findsOneWidget);
await tester.tap(find.text('increment'));
await tester.pump();
await tester.tap(find.text('increment'));
await tester.pump();
expect(find.text('count: 2'), findsOneWidget);
await tester.restartAndRestore();
expect(find.text('p2'), findsOneWidget);
expect(find.text('count: 2'), findsOneWidget);
tester.state<NavigatorState>(find.byType(Navigator)).pop();
await tester.pumpAndSettle();
expect(find.text('p1'), findsOneWidget);
expect(find.text('count: 1'), findsOneWidget);
});
}
class RtlOverrideWidgetsDelegate extends LocalizationsDelegate<WidgetsLocalizations> {
......@@ -527,3 +589,42 @@ class _KeepsStateTestWidgetState extends State<KeepsStateTestWidget> {
);
}
}
class TestRestorableWidget extends StatefulWidget {
const TestRestorableWidget({Key? key, required this.restorationId}) : super(key: key);
final String restorationId;
@override
State<StatefulWidget> createState() => _TestRestorableWidgetState();
}
class _TestRestorableWidgetState extends State<TestRestorableWidget> with RestorationMixin {
@override
String? get restorationId => widget.restorationId;
final RestorableInt counter = RestorableInt(0);
@override
void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
registerForRestoration(counter, 'counter');
}
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Text(widget.restorationId),
Text('count: ${counter.value}'),
CupertinoButton(
onPressed: () {
setState(() {
counter.value++;
});
},
child: const Text('increment'),
),
],
);
}
}
......@@ -913,6 +913,65 @@ void main() {
expect(find.text('subpage'), findsOneWidget);
expect(find.text('home'), findsOneWidget);
});
testWidgets('MaterialPage restores its state', (WidgetTester tester) async {
await tester.pumpWidget(
RootRestorationScope(
restorationId: 'root',
child: Directionality(
textDirection: TextDirection.ltr,
child: Navigator(
onPopPage: (Route<dynamic> route, dynamic result) { return false; },
pages: const <Page<Object?>>[
MaterialPage<void>(
restorationId: 'p1',
child: TestRestorableWidget(restorationId: 'p1'),
),
],
restorationScopeId: 'nav',
onGenerateRoute: (RouteSettings settings) {
return MaterialPageRoute<void>(
settings: settings,
builder: (BuildContext context) {
return TestRestorableWidget(restorationId: settings.name!);
},
);
},
),
),
),
);
expect(find.text('p1'), findsOneWidget);
expect(find.text('count: 0'), findsOneWidget);
await tester.tap(find.text('increment'));
await tester.pump();
expect(find.text('count: 1'), findsOneWidget);
tester.state<NavigatorState>(find.byType(Navigator)).restorablePushNamed('p2');
await tester.pumpAndSettle();
expect(find.text('p1'), findsNothing);
expect(find.text('p2'), findsOneWidget);
await tester.tap(find.text('increment'));
await tester.pump();
await tester.tap(find.text('increment'));
await tester.pump();
expect(find.text('count: 2'), findsOneWidget);
await tester.restartAndRestore();
expect(find.text('p2'), findsOneWidget);
expect(find.text('count: 2'), findsOneWidget);
tester.state<NavigatorState>(find.byType(Navigator)).pop();
await tester.pumpAndSettle();
expect(find.text('p1'), findsOneWidget);
expect(find.text('count: 1'), findsOneWidget);
});
}
class TransitionDetector extends DefaultTransitionDelegate<void> {
......@@ -993,3 +1052,42 @@ class _KeepsStateTestWidgetState extends State<KeepsStateTestWidget> {
);
}
}
class TestRestorableWidget extends StatefulWidget {
const TestRestorableWidget({Key? key, required this.restorationId}) : super(key: key);
final String restorationId;
@override
State<StatefulWidget> createState() => _TestRestorableWidgetState();
}
class _TestRestorableWidgetState extends State<TestRestorableWidget> with RestorationMixin {
@override
String? get restorationId => widget.restorationId;
final RestorableInt counter = RestorableInt(0);
@override
void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
registerForRestoration(counter, 'counter');
}
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Text(widget.restorationId),
Text('count: ${counter.value}'),
ElevatedButton(
onPressed: () {
setState(() {
counter.value++;
});
},
child: const Text('increment'),
),
],
);
}
}
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