🔨

【Flutter】画面遷移ができない時の対処法

2021/06/28に公開

今回は、画面遷移をしようと思ったのに、画面遷移できない! となった時の解決策です。

エラー文:Navigator operation requested with a context that does not include a Navigator.

※そもそもの書き方が違っている場合のものではないので、この記事の方法で直らない方は、今一度公式ドキュメントをよくみてください。
https://flutter.dev/docs/cookbook/navigation/navigation-basics

結論:return MaterialApp()の中に画面遷移を入れてないけない

Flutterでは、メインとなるクラスで、MaterialApp()を返すことで、画面を表示します。(そうではないパターンもあるかもしれませんが知りません。)
これを最も簡単に書くと、次のようになります。これは、MaterialApp()の中に直接コードを全部書くようになっています。

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

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Welcome to Flutter',
      home: Scaffold(
       //ここに画面となるコードを書く
       //今回の記事では、ここに画面遷移のコードが書いてあるということ
      )
    );
  }
}

初学者の方にとっては、これが一番わかりやすいので、多くの入門記事でこのように書かれていますが、このまま書いていくと、画面遷移がうまくいかなくなってしまいます。
その原因は、MaterialApp()を返すクラスと画面遷移のコードが同じ場所にあってはいけないということです。

解決策:画面遷移のコードを書く部分をMaterialAppから分離する

もっと端的にいうと、MaterialApp()を返すクラス内に、画面遷移をするためのコードを書いてはいけないということです。なので、こうします。

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

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Welcome to Flutter',
      home: Home() //画面遷移をする部分を下のように別のクラスで定義し、それを読み込む
    );
  }
}

// 画面遷移をする部分のコード
class Home extends StatelessWidget {
	
	Widget build(BuildContext context) {
		return Scaffold(
		       //ここに画面となるコードを書く
		       //今回の記事では、ここに画面遷移のコードが書いてあるということ
		);
	}
}

このように、画面遷移のコードを書く部分を別のクラスで定義することで、画面遷移ができるようになります。

余談:画面遷移しなくても、クラスは分けるべき

Futterでは、ひいてはプログラミングでは、オブジェクト指向という考え方があり、機能ごとにクラスを分けて別々に保管しておくことが一般的です。なので、今回の記事の画面遷移に限らず、クラスを分けて書くようにしておくことをお勧めします。

Flutterでは、エディタで "stl"とうつと、自動でStatelessWidgetを作成してくれるので、非常に簡単にクラスを分けることができますので、試してみてください。

Discussion