LoginSignup
14
5

More than 3 years have passed since last update.

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

Posted at

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()),
                );
              },
            ),
          ]),
        ),
      ),
    );
  }
}

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

14
5
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
5