296 lines
8 KiB
Dart
296 lines
8 KiB
Dart
// Copyright 2014 The Flutter Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
import 'package:flutter/cupertino.dart';
|
|
|
|
/// Flutter code sample for [CupertinoSheetRoute] with restorable state and nested navigation.
|
|
|
|
void main() => runApp(const RestorableSheetExampleApp());
|
|
|
|
class RestorableSheetExampleApp extends StatelessWidget {
|
|
const RestorableSheetExampleApp({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return const CupertinoApp(
|
|
restorationScopeId: 'sheet-app',
|
|
title: 'Restorable Sheet',
|
|
home: RestorableSheet(restorationId: 'sheet'),
|
|
);
|
|
}
|
|
}
|
|
|
|
class RestorableSheet extends StatefulWidget {
|
|
const RestorableSheet({super.key, this.restorationId});
|
|
|
|
final String? restorationId;
|
|
|
|
@override
|
|
State<RestorableSheet> createState() => _RestorableSheetState();
|
|
}
|
|
|
|
@pragma('vm:entry-point')
|
|
class _RestorableSheetState extends State<RestorableSheet>
|
|
with RestorationMixin {
|
|
final RestorableInt _counter = RestorableInt(0);
|
|
late RestorableRouteFuture<int?> _restorableSheetRouteFuture;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_restorableSheetRouteFuture = RestorableRouteFuture<int?>(
|
|
onComplete: _changeCounter,
|
|
onPresent: (NavigatorState navigator, Object? arguments) {
|
|
return navigator.restorablePush(
|
|
_counterSheetBuilder,
|
|
arguments: _counter.value,
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
@override
|
|
String? get restorationId => widget.restorationId;
|
|
|
|
@override
|
|
void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
|
|
registerForRestoration(_counter, 'count');
|
|
registerForRestoration(_restorableSheetRouteFuture, 'sheet_route_future');
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_counter.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
@pragma('vm:entry-point')
|
|
static Route<void> _counterSheetBuilder(
|
|
BuildContext context,
|
|
Object? arguments,
|
|
) {
|
|
return CupertinoSheetRoute<int?>(
|
|
builder: (BuildContext context) {
|
|
return Navigator(
|
|
restorationScopeId: 'nested-nav',
|
|
onGenerateRoute: (RouteSettings settings) {
|
|
return CupertinoPageRoute<void>(
|
|
settings: settings,
|
|
builder: (BuildContext context) {
|
|
return PopScope(
|
|
canPop: settings.name != '/',
|
|
onPopInvokedWithResult: (bool didPop, Object? result) {
|
|
if (didPop) {
|
|
return;
|
|
}
|
|
Navigator.of(context).pop();
|
|
},
|
|
child: CounterSheetScaffold(counter: arguments! as int),
|
|
);
|
|
},
|
|
);
|
|
},
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
void _changeCounter(int? newCounter) {
|
|
if (newCounter != null) {
|
|
setState(() {
|
|
_counter.value = newCounter;
|
|
});
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return CupertinoPageScaffold(
|
|
navigationBar: const CupertinoNavigationBar(
|
|
middle: Text('Sheet Example'),
|
|
automaticBackgroundVisibility: false,
|
|
),
|
|
child: Center(
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: <Widget>[
|
|
const Text('Counter current value:'),
|
|
Text('${_counter.value}'),
|
|
CupertinoButton(
|
|
child: const Text('Open Sheet'),
|
|
onPressed: () {
|
|
_restorableSheetRouteFuture.present();
|
|
},
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class CounterSheetScaffold extends StatefulWidget {
|
|
const CounterSheetScaffold({super.key, required this.counter});
|
|
|
|
final int counter;
|
|
|
|
@override
|
|
State<CounterSheetScaffold> createState() => _CounterSheetScaffoldState();
|
|
}
|
|
|
|
class _CounterSheetScaffoldState extends State<CounterSheetScaffold>
|
|
with RestorationMixin {
|
|
late RestorableInt _counter;
|
|
late RestorableRouteFuture<int?> _multiplicationRouteFuture;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_counter = RestorableInt(widget.counter);
|
|
_multiplicationRouteFuture = RestorableRouteFuture<int?>(
|
|
onComplete: _changeCounter,
|
|
onPresent: (NavigatorState navigator, Object? arguments) {
|
|
return navigator.restorablePush(
|
|
_multiplicationRouteBuilder,
|
|
arguments: _counter.value,
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
@pragma('vm:entry-point')
|
|
static Route<void> _multiplicationRouteBuilder(
|
|
BuildContext context,
|
|
Object? arguments,
|
|
) {
|
|
return CupertinoPageRoute<int?>(
|
|
settings: const RouteSettings(name: '/multiplication'),
|
|
builder: (BuildContext context) {
|
|
return MultiplicationPage(counter: arguments! as int);
|
|
},
|
|
);
|
|
}
|
|
|
|
void _changeCounter(int? newCounter) {
|
|
if (newCounter != null) {
|
|
setState(() {
|
|
_counter.value = newCounter;
|
|
});
|
|
}
|
|
}
|
|
|
|
@override
|
|
String? get restorationId => 'sheet_scaffold';
|
|
|
|
@override
|
|
void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
|
|
registerForRestoration(_counter, 'sheet_counter');
|
|
registerForRestoration(_multiplicationRouteFuture, 'multiplication_route');
|
|
if (!_counter.enabled) {
|
|
_counter = RestorableInt(widget.counter);
|
|
}
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_counter.dispose();
|
|
_multiplicationRouteFuture.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return CupertinoPageScaffold(
|
|
child: Center(
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: <Widget>[
|
|
Text('Current Count: ${_counter.value}'),
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: <Widget>[
|
|
CupertinoButton(
|
|
onPressed: () {
|
|
setState(() => _counter.value = _counter.value - 1);
|
|
},
|
|
child: const Text('Decrease'),
|
|
),
|
|
CupertinoButton(
|
|
onPressed: () {
|
|
setState(() => _counter.value = _counter.value + 1);
|
|
},
|
|
child: const Text('Increase'),
|
|
),
|
|
],
|
|
),
|
|
CupertinoButton(
|
|
onPressed: () => _multiplicationRouteFuture.present(),
|
|
child: const Text('Go to Multiplication Page'),
|
|
),
|
|
CupertinoButton(
|
|
onPressed: () => Navigator.of(
|
|
context,
|
|
rootNavigator: true,
|
|
).pop(_counter.value),
|
|
child: const Text('Pop Sheet'),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class MultiplicationPage extends StatefulWidget {
|
|
const MultiplicationPage({super.key, required this.counter});
|
|
|
|
final int counter;
|
|
|
|
@override
|
|
State<MultiplicationPage> createState() => _MultiplicationPageState();
|
|
}
|
|
|
|
class _MultiplicationPageState extends State<MultiplicationPage>
|
|
with RestorationMixin {
|
|
late final RestorableInt _counter = RestorableInt(widget.counter);
|
|
|
|
@override
|
|
String? get restorationId => 'multiplication_page';
|
|
|
|
@override
|
|
void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
|
|
registerForRestoration(_counter, 'multi_counter');
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_counter.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return CupertinoPageScaffold(
|
|
child: Center(
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: <Widget>[
|
|
const Text('Current Count'),
|
|
Text(_counter.value.toString()),
|
|
CupertinoButton(
|
|
onPressed: () {
|
|
setState(() => _counter.value = _counter.value * 2);
|
|
},
|
|
child: const Text('Double it'),
|
|
),
|
|
CupertinoButton(
|
|
onPressed: () => Navigator.pop(context, _counter.value),
|
|
child: const Text('Pass it on to the last sheet'),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|