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 | |
5 | import 'package:flutter/cupertino.dart'; |
6 | |
7 | /// Flutter code sample for [CupertinoSheetRoute] with restorable state and nested navigation. |
8 | |
9 | void main() => runApp(const RestorableSheetExampleApp()); |
10 | |
11 | class 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 | |
24 | class 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') |
34 | class _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 | |
126 | class 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 | |
135 | class _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 | |
228 | class 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 | |
237 | class _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 |
Definitions
- main
- RestorableSheetExampleApp
- RestorableSheetExampleApp
- build
- RestorableSheet
- RestorableSheet
- createState
- _RestorableSheetState
- initState
- restorationId
- restoreState
- dispose
- _counterSheetBuilder
- _changeCounter
- build
- CounterSheetScaffold
- CounterSheetScaffold
- createState
- _CounterSheetScaffoldState
- initState
- _multiplicationRouteBuilder
- _changeCounter
- restorationId
- restoreState
- dispose
- build
- MultiplicationPage
- MultiplicationPage
- createState
- _MultiplicationPageState
- restorationId
- restoreState
- dispose
Learn more about Flutter for embedded and desktop on industrialflutter.com