restorable_route_future.0.dart 4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
// 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.

// Flutter code sample for RestorableRouteFuture

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
12
  const MyApp({super.key});
13 14 15 16 17 18 19 20 21 22 23 24 25 26

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      restorationScopeId: 'app',
      home: Scaffold(
        appBar: AppBar(title: const Text('RestorableRouteFuture Example')),
        body: const MyHome(),
      ),
    );
  }
}

class MyHome extends StatefulWidget {
27
  const MyHome({super.key});
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106

  @override
  State<MyHome> createState() => _MyHomeState();
}

class _MyHomeState extends State<MyHome> with RestorationMixin {
  final RestorableInt _lastCount = RestorableInt(0);
  late RestorableRouteFuture<int> _counterRoute;

  @override
  String get restorationId => 'home';

  @override
  void initState() {
    super.initState();
    _counterRoute = RestorableRouteFuture<int>(
        onPresent: (NavigatorState navigator, Object? arguments) {
      // Defines what route should be shown (and how it should be added
      // to the navigator) when `RestorableRouteFuture.present` is called.
      return navigator.restorablePush(
        _counterRouteBuilder,
        arguments: arguments,
      );
    }, onComplete: (int count) {
      // Defines what should happen with the return value when the route
      // completes.
      setState(() {
        _lastCount.value = count;
      });
    });
  }

  @override
  void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
    // Register the `RestorableRouteFuture` with the state restoration framework.
    registerForRestoration(_counterRoute, 'route');
    registerForRestoration(_lastCount, 'count');
  }

  @override
  void dispose() {
    super.dispose();
    _lastCount.dispose();
    _counterRoute.dispose();
  }

  // A static `RestorableRouteBuilder` that can re-create the route during
  // state restoration.
  static Route<int> _counterRouteBuilder(
      BuildContext context, Object? arguments) {
    return MaterialPageRoute<int>(
      builder: (BuildContext context) => MyCounter(
        title: arguments!.toString(),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          Text('Last count: ${_lastCount.value}'),
          ElevatedButton(
            onPressed: () {
              // Show the route defined by the `RestorableRouteFuture`.
              _counterRoute.present('Awesome Counter');
            },
            child: const Text('Open Counter'),
          ),
        ],
      ),
    );
  }
}

// Widget for the route pushed by the `RestorableRouteFuture`.
class MyCounter extends StatefulWidget {
107
  const MyCounter({super.key, required this.title});
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157

  final String title;

  @override
  State<MyCounter> createState() => _MyCounterState();
}

class _MyCounterState extends State<MyCounter> with RestorationMixin {
  final RestorableInt _count = RestorableInt(0);

  @override
  String get restorationId => 'counter';

  @override
  void restoreState(RestorationBucket? oldBucket, bool initialRestore) {
    registerForRestoration(_count, 'count');
  }

  @override
  void dispose() {
    super.dispose();
    _count.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        leading: BackButton(
          onPressed: () {
            // Return the current count of the counter from this route.
            Navigator.of(context).pop(_count.value);
          },
        ),
      ),
      body: Center(
        child: Text('Count: ${_count.value}'),
      ),
      floatingActionButton: FloatingActionButton(
        child: const Icon(Icons.add),
        onPressed: () {
          setState(() {
            _count.value++;
          });
        },
      ),
    );
  }
}