【Flutter】画面遷移実装時のエラー（Navigator operation requested with a context that does not include a Navigator.）の解決策

Flutterを学習中です。

NavigationWidgetを用いて画面遷移を実装中にエラーが発生し、詰まった部分があった為
解決策を記載いたします。

####環境
```
Mac OS
Flutter1.20.4(channel stable)
VS code
```
####実装したいこと

作った料理のレシピをストックできるアプリを開発したく、
ホーム画面のボタンをクリックすると、レシピ追加画面に移行するように
画面遷移を実装したい。

####エラー文

大量のエラー・・・

```
I/flutter (23646): ══╡ EXCEPTION CAUGHT BY GESTURE ╞═══════════════════════════════════════════════════════════════════
I/flutter (23646): The following assertion was thrown while handling a gesture:
I/flutter (23646): Navigator operation requested with a context that does not include a Navigator.
I/flutter (23646): The context used to push or pop routes from the Navigator must be that of a widget that is a
I/flutter (23646): descendant of a Navigator widget.
I/flutter (23646):
I/flutter (23646): When the exception was thrown, this was the stack:
I/flutter (23646): #0      Navigator.of.<anonymous closure> (package:flutter/src/widgets/navigator.dart:2190:9)
I/flutter (23646): #1      Navigator.of (package:flutter/src/widgets/navigator.dart:2197:6)
I/flutter (23646): #2      Navigator.push (package:flutter/src/widgets/navigator.dart:1801:22)
I/flutter (23646): #3      CookApp.build.<anonymous closure> (package:mytodoapp/main.dart:27:29)
I/flutter (23646): #4      _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:992:19)
I/flutter (23646): #5      _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:1098:38)
I/flutter (23646): #6      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:184:24)
I/flutter (23646): #7      TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:524:11)
I/flutter (23646): #8      BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:284:5)
I/flutter (23646): #9      BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:219:7)
I/flutter (23646): #10     PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:477:9)
I/flutter (23646): #11     PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:78:12)
I/flutter (23646): #12     PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:124:9)
I/flutter (23646): #13     _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:377:8)
I/flutter (23646): #14     PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:122:18)
I/flutter (23646): #15     PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:108:7)
I/flutter (23646): #16     GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:220:19)
I/flutter (23646): #17     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:200:22)
I/flutter (23646): #18     GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:158:7)
I/flutter (23646): #19     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:104:7)
I/flutter (23646): #20     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:88:7)
I/flutter (23646): #24     _invoke1 (dart:ui/hooks.dart:267:10)
I/flutter (23646): #25     _dispatchPointerDataPacket (dart:ui/hooks.dart:176:5)
I/flutter (23646): (elided 3 frames from dart:async)
I/flutter (23646):
I/flutter (23646): Handler: "onTap"
I/flutter (23646): Recognizer:
I/flutter (23646):   TapGestureRecognizer#aaa22
I/flutter (23646): ════════════════════════════════════════════════════════════════════════════════════════════════════
I/flutter (23646): Another exception was thrown: Navigator operation requested with a context that does not include a Navigator.
I/flutter (23646): Another exception was thrown: Navigator operation requested with a context that does not include a Navigator.

```

####エラーが発生した際のコード文

```:main.dart(遷移元)
import 'package:flutter/material.dart';
import 'package:mytodoapp/add_recipe_page.dart';

void main() => runApp(CookApp());

class CookApp extends StatelessWidget {
  var titleText = 'cookapp';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          leading: Icon(Icons.menu),
          title: Text('レシピ一覧'),
        ),
        body: Container(
          child: Center(
            child: Column(children: <Widget>[
              Text(titleText),

              RaisedButton(
                child: Text("Button"),
                color: Colors.orange,
                textColor: Colors.white,
                onPressed: () {
                  Navigator.push(
                    context,
                    MaterialPageRoute(builder: (context) => AddRecipe()),
                  );
                },
              ),
            ]),
          ),
        ),
      ),
    );
  }
}
```

```add_recipe.dart(遷移先)

import 'package:flutter/material.dart';

void main() => runApp(AddRecipe());

class AddRecipe extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('レシピ追加画面'),
          leading: Icon(Icons.add_alert),
        ),
        body: Container(
          child: Center(
            child: Text('レシピ追加'),
          ),
        ),
      ),
    );
  }
}
```

####エラーの原因

エラーで画面遷移ができなかった理由としては、
【MaterialAppWidgetの理解】にありました。

上記コードではMaterialAppを遷移元のページと遷移先のページの2箇所に記載していますが、
アプリ内で一箇所のみに記載すべきとのことです。

また、MaterialAppはNavigatorとの間にはワンクッション空けて記載する方が好ましい様です。
（return MaterialAppのかっこの中にはNavigatorを書かない）

以上のことを踏まえて、コードを修正しました。

```main.dart(遷移元)

//MaterialAppを返すクラスを別途追加

class CookApp extends StatelessWidget {
  var titleText = 'cookapp';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Home(titleText: titleText),
    );
  }
}

class Home extends StatelessWidget {
  final String titleText;

  const Home({this.titleText});

  @override
  Widget build(BuildContext context) {
//Scaffoldm内に Navigatorを配置

    return Scaffold(
      appBar: AppBar(
        leading: Icon(Icons.menu),
        title: Text('レシピ一覧'),
      ),
      body: Container(
        child: Center(
          child: Column(children: <Widget>[
            Text(titleText),
            RaisedButton(
              child: Text("Button"),
              color: Colors.orange,
              textColor: Colors.white,
              onPressed: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => AddRecipe()),
                );
              },
            ),
          ]),
        ),
      ),
    );
  }
}

```

無事に画面遷移が成功することが確認できました！