1// Copyright 2014 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5import 'package:flutter/cupertino.dart';
6
7/// Flutter code sample for [CupertinoSheetRoute] with restorable state and nested navigation.
8
9void main() => runApp(const RestorableSheetExampleApp());
10
11class RestorableSheetExampleApp extends StatelessWidget {
12 const RestorableSheetExampleApp({super.key});
13
14 @override
15 Widget build(BuildContext context) {
16 return const CupertinoApp(
17 restorationScopeId: 'sheet-app',
18 title: 'Restorable Sheet',
19 home: RestorableSheet(restorationId: 'sheet'),
20 );
21 }
22}
23
24class RestorableSheet extends StatefulWidget {
25 const RestorableSheet({super.key, this.restorationId});
26
27 final String? restorationId;
28
29 @override
30 State<RestorableSheet> createState() => _RestorableSheetState();
31}
32
33@pragma('vm:entry-point')
34class _RestorableSheetState extends State<RestorableSheet> with RestorationMixin {
35 final RestorableInt _counter = RestorableInt(0);
36 late RestorableRouteFuture<int?> _restorableSheetRouteFuture;
37
38 @override
39 void initState() {
40 super.initState();
41 _restorableSheetRouteFuture = RestorableRouteFuture<int?>(
42 onComplete: _changeCounter,
43 onPresent: (NavigatorState navigator, Object? arguments) {
44 return navigator.restorablePush(_counterSheetBuilder, arguments: _counter.value);
45 },
46 );
47 }
48
49 @override
50 String? get restorationId => widget.restorationId;
51
52 @override
53 void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
54 registerForRestoration(_counter, 'count');
55 registerForRestoration(_restorableSheetRouteFuture, 'sheet_route_future');
56 }
57
58 @override
59 void dispose() {
60 _counter.dispose();
61 super.dispose();
62 }
63
64 @pragma('vm:entry-point')
65 static Route<void> _counterSheetBuilder(BuildContext context, Object? arguments) {
66 return CupertinoSheetRoute<int?>(
67 builder: (BuildContext context) {
68 return Navigator(
69 restorationScopeId: 'nested-nav',
70 onGenerateRoute: (RouteSettings settings) {
71 return CupertinoPageRoute<void>(
72 settings: settings,
73 builder: (BuildContext context) {
74 return PopScope(
75 canPop: settings.name != '/',
76 onPopInvokedWithResult: (bool didPop, Object? result) {
77 if (didPop) {
78 return;
79 }
80 Navigator.of(context).pop();
81 },
82 child: CounterSheetScaffold(counter: arguments! as int),
83 );
84 },
85 );
86 },
87 );
88 },
89 );
90 }
91
92 void _changeCounter(int? newCounter) {
93 if (newCounter != null) {
94 setState(() {
95 _counter.value = newCounter;
96 });
97 }
98 }
99
100 @override
101 Widget build(BuildContext context) {
102 return CupertinoPageScaffold(
103 navigationBar: const CupertinoNavigationBar(
104 middle: Text('Sheet Example'),
105 automaticBackgroundVisibility: false,
106 ),
107 child: Center(
108 child: Column(
109 mainAxisAlignment: MainAxisAlignment.center,
110 children: <Widget>[
111 const Text('Counter current value:'),
112 Text('${_counter.value}'),
113 CupertinoButton(
114 child: const Text('Open Sheet'),
115 onPressed: () {
116 _restorableSheetRouteFuture.present();
117 },
118 ),
119 ],
120 ),
121 ),
122 );
123 }
124}
125
126class CounterSheetScaffold extends StatefulWidget {
127 const CounterSheetScaffold({super.key, required this.counter});
128
129 final int counter;
130
131 @override
132 State<CounterSheetScaffold> createState() => _CounterSheetScaffoldState();
133}
134
135class _CounterSheetScaffoldState extends State<CounterSheetScaffold> with RestorationMixin {
136 late RestorableInt _counter;
137 late RestorableRouteFuture<int?> _multiplicationRouteFuture;
138
139 @override
140 void initState() {
141 super.initState();
142 _counter = RestorableInt(widget.counter);
143 _multiplicationRouteFuture = RestorableRouteFuture<int?>(
144 onComplete: _changeCounter,
145 onPresent: (NavigatorState navigator, Object? arguments) {
146 return navigator.restorablePush(_multiplicationRouteBuilder, arguments: _counter.value);
147 },
148 );
149 }
150
151 @pragma('vm:entry-point')
152 static Route<void> _multiplicationRouteBuilder(BuildContext context, Object? arguments) {
153 return CupertinoPageRoute<int?>(
154 settings: const RouteSettings(name: '/multiplication'),
155 builder: (BuildContext context) {
156 return MultiplicationPage(counter: arguments! as int);
157 },
158 );
159 }
160
161 void _changeCounter(int? newCounter) {
162 if (newCounter != null) {
163 setState(() {
164 _counter.value = newCounter;
165 });
166 }
167 }
168
169 @override
170 String? get restorationId => 'sheet_scaffold';
171
172 @override
173 void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
174 registerForRestoration(_counter, 'sheet_counter');
175 registerForRestoration(_multiplicationRouteFuture, 'multiplication_route');
176 if (!_counter.enabled) {
177 _counter = RestorableInt(widget.counter);
178 }
179 }
180
181 @override
182 void dispose() {
183 _counter.dispose();
184 _multiplicationRouteFuture.dispose();
185 super.dispose();
186 }
187
188 @override
189 Widget build(BuildContext context) {
190 return CupertinoPageScaffold(
191 child: Center(
192 child: Column(
193 mainAxisAlignment: MainAxisAlignment.center,
194 children: <Widget>[
195 Text('Current Count: ${_counter.value}'),
196 Row(
197 mainAxisAlignment: MainAxisAlignment.center,
198 children: <Widget>[
199 CupertinoButton(
200 onPressed: () {
201 setState(() => _counter.value = _counter.value - 1);
202 },
203 child: const Text('Decrease'),
204 ),
205 CupertinoButton(
206 onPressed: () {
207 setState(() => _counter.value = _counter.value + 1);
208 },
209 child: const Text('Increase'),
210 ),
211 ],
212 ),
213 CupertinoButton(
214 onPressed: () => _multiplicationRouteFuture.present(),
215 child: const Text('Go to Multiplication Page'),
216 ),
217 CupertinoButton(
218 onPressed: () => Navigator.of(context, rootNavigator: true).pop(_counter.value),
219 child: const Text('Pop Sheet'),
220 ),
221 ],
222 ),
223 ),
224 );
225 }
226}
227
228class MultiplicationPage extends StatefulWidget {
229 const MultiplicationPage({super.key, required this.counter});
230
231 final int counter;
232
233 @override
234 State<MultiplicationPage> createState() => _MultiplicationPageState();
235}
236
237class _MultiplicationPageState extends State<MultiplicationPage> with RestorationMixin {
238 late final RestorableInt _counter = RestorableInt(widget.counter);
239
240 @override
241 String? get restorationId => 'multiplication_page';
242
243 @override
244 void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
245 registerForRestoration(_counter, 'multi_counter');
246 }
247
248 @override
249 void dispose() {
250 _counter.dispose();
251 super.dispose();
252 }
253
254 @override
255 Widget build(BuildContext context) {
256 return CupertinoPageScaffold(
257 child: Center(
258 child: Column(
259 mainAxisAlignment: MainAxisAlignment.center,
260 children: <Widget>[
261 const Text('Current Count'),
262 Text(_counter.value.toString()),
263 CupertinoButton(
264 onPressed: () {
265 setState(() => _counter.value = _counter.value * 2);
266 },
267 child: const Text('Double it'),
268 ),
269 CupertinoButton(
270 onPressed: () => Navigator.pop(context, _counter.value),
271 child: const Text('Pass it on to the last sheet'),
272 ),
273 ],
274 ),
275 ),
276 );
277 }
278}
279

Provided by KDAB

Privacy Policy
Learn more about Flutter for embedded and desktop on industrialflutter.com