リスト 5.7 / 5.8 / 5.9


import 'package:flutter/material.dart';

// リスト 5.7
void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final AppRouteInformationParser _appRouteInformationParser =
      AppRouteInformationParser();
  final AppRouterDelegate _appRouterDelegate = AppRouterDelegate();

  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routerDelegate: _appRouterDelegate,
      routeInformationParser: _appRouteInformationParser
    );
  }
}

// リスト 5.8
class AppRouterDelegate extends RouterDelegate<Object>
    with ChangeNotifier, PopNavigatorRouterDelegateMixin<Object> {
  @override
  final GlobalKey<NavigatorState> navigatorKey;

  AppRouterDelegate() : navigatorKey = GlobalKey<NavigatorState>();
  String _selectedWord = '';

  @override
  Widget build(BuildContext context) {
    return Navigator(
      key: navigatorKey,
      pages: [
        MaterialPage<Page>(
          key: ValueKey('TestPage'), child: TestPage(_changeSelectedWord)
        ),
        if (_selectedWord != '')
          MaterialPage<Page>(
            key: ValueKey('DetailPage$_selectedWord'),
            child: DetailPage(_selectedWord)
          )
      ],
      onPopPage: (route, dynamic result) {
        if (!route.didPop(result)) {
          return false;
        }
        _selectedWord = '';
        notifyListeners();
        return true;
      }
    );
  }

  @override
  Future<void> setNewRoutePath(void configuration) async {
    // do nothing
  }

  void _changeSelectedWord(String word) {
    _selectedWord = word;
    notifyListeners();
  }
}

// リスト 5.9
class AppRouteInformationParser extends RouteInformationParser<Object> {
  @override
  Future<Object> parseRouteInformation(
                    RouteInformation routeInformation) async {
    return '';
  }
}

// リスト 5.6
class TestPage extends StatelessWidget {
  TestPage(this.onTap);

  final Function(String) onTap;
  static const String _title = 'TestPage';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: _title,
      home: Scaffold(
        appBar: AppBar(title: const Text('TestPage')),
        body: Center(
          child: Padding(
            padding: EdgeInsets.all(20),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                ElevatedButton(
                  onPressed: () => onTap('A'), child: Text('A')
                ),
                ElevatedButton(
                  onPressed: () => onTap('B'), child: Text('B')
                ),
                ElevatedButton(
                  onPressed: () => onTap('C'), child: Text('C')
                )
              ]
            )
          )
        )
      )
    );
  }
}

class DetailPage extends StatelessWidget {
  DetailPage(this.word);

  final String word;
  static const String _title = 'DetailPage';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: _title,
      home: Scaffold(
        appBar: AppBar(
          title: Text(word),
          leading: IconButton(
            icon: Icon(
              Icons.arrow_back,
              color: Colors.white,
            ),
            onPressed: () => Navigator.pop(context)
          )
        ),
        body: Center(
          child: Padding(
            padding: EdgeInsets.all(20),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                TextButton(
                  onPressed: () => Navigator.push(
                    context,
                    MaterialPageRoute<void>(
                      builder: (context) => ItemPage('$word-1')
                    )
                  ),
                  child: Text('1')
                ),
                TextButton(
                  onPressed: () => Navigator.push(
                    context,
                    MaterialPageRoute<void>(
                      builder: (context) => ItemPage('$word-2')
                    )
                  ),
                  child: Text('2')
                ),
                TextButton(
                  onPressed: () => Navigator.push(
                    context,
                    MaterialPageRoute<void>(
                      builder: (context) => ItemPage('$word-3')
                    )
                  ),
                  child: Text('3')
                )
              ]
            )
          )
        )
      )
    );
  }
}

class ItemPage extends StatelessWidget {
  ItemPage(this.itemName);

  final String itemName;
  static const String _title = 'ItemPage';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: _title,
      home: Scaffold(
        appBar: AppBar(
          title: Text(itemName),
          leading: IconButton(
            icon: Icon(
              Icons.arrow_back,
              color: Colors.white,
            ),
            onPressed: () => Navigator.pop(context)
          )
        ),
        body: Center(
          child: Text(itemName),
        )
      )
    );
  }
}