【Flutter】画面遷移の実装方法【サンプルコードあり】

今回は画面遷移の実装方法を備忘録として紹介してみます。

やはりアプリを作る以上、必ず実装する処理の1つにこの画面遷移があると思います。

逆にページが遷移しないアプリを見つけるほうが難しいような。

(webだったらSPAとかあるけど)

Flutterでは、画面遷移にはNavigatorというWidgetを使って実装します。アプリを作る上でかなり使うWidgetだから是非覚えてみるのがおすすめ。

Widgetについてわからない方は下の記事を参考にしてみてください。

【Flutter】UI構築する際の基本Widgetついて解説!【サンプルコードあり】

Navigator

Navigatorはページ遷移を実装するために用いられるWidgetなんですが実装方法は2通りあって、

  1. あらかじめ最初にルーティングを決めておいて遷移
  2. その都度画面を接続設定して遷移

の2つ。正直1つ目の方法はあまり使われないし、自分で記述していて分かりづらいと思うので個人的には2つ目の方法がおすすめ。というか僕自身それしか知らないです。

別にこの両方とも覚えないといけない訳ではないですし、片方覚えておけば全然問題ないです。

知識として押さえておきたいって人はGoogle公式のドキュメントを見るのが分かりやすくておすすめです。

ドキュメント自体は英語で書かれてるけど特に難しい事は書いてないので見てみて下さい。

https://flutter.dev/docs/cookbook/navigation/named-routes

今回は2つ目の方法を詳しく解説していきます!

実装方法

最初に全体のコードを載せていきます。

▼main.dart

main.dart
import 'package:flutter/material.dart';
import 'next_page.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(
          'スクショ!',
        ),
      ),
      body: Center(
        child: ElevatedButton(
          child: Text('次のページ'),
          onPressed: () {
// -*--*--*--*--*- Navigator -*--*--*--*--*-
            Navigator.push(
                context, MaterialPageRoute(builder: (context) => NextPage()));
// -*--*--*--*--*- Navigator -*--*--*--*--*-
          },
        ),
      ),
    );
  }
}
next_page.dart
import 'package:flutter/material.dart';
import 'next_page.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(
          'スクショ!',
        ),
      ),
      body: Center(
        child: ElevatedButton(
          child: Text('次のページ'),
          onPressed: () {
// -*--*--*--*--*- Navigator -*--*--*--*--*-
            Navigator.push(
                context, MaterialPageRoute(builder: (context) => NextPage()));
// -*--*--*--*--*- Navigator -*--*--*--*--*-
          },
        ),
      ),
    );
  }
}

遷移前

遷移後

全体のコードとしてはこんな感じ。Navigatorが使われている箇所だけを抜き出すと以下になります。

main.dart
 child: ElevatedButton(
          child: Text('次のページ'),
          onPressed: () {
            Navigator.push(
                context, MaterialPageRoute(builder: (context) => NextPage()));
          },
        ),

まず遷移元のファイルではElevatedButtononPressedプロパティ内でNavigatorのpushメソッドを使用していて、ボタンが押されたらNavigatorが動作する仕組みになっています。

第一引数でcontext、これは一言で言うと「今このWidgetがどの位置に存在するのか」という位置情報を参照しています。

突き詰めると難しい話になるので、これはおまじないとして覚えるのがいいと思います。

第二引数でMaterialPageRouteを指定していて、これは画面遷移する時のアニメーションを指定するための設定で、MaterialPageRouteを指定すればマテリアルデザインのアニメーション、CupertinoPageRouteと指定すればiOS風なアニメーションを指定できます。

ここのMaterialPageRouteではbuilderプロパティの返り値として遷移先ファイルのNextPageクラスを指定しています。これによってファイル間が接続されて、ページが遷移されます。

next_page.dart
    child: ElevatedButton(
          child: Text('前のページに戻るよ'),
          onPressed: () {
            Navigator.pop(context);
          },
        ),

戻る際はもっと簡単です。

遷移先のnextr_page.dart画面から遷移元のmain.dart画面に戻りたい時はonPressedプロパティ内ででNavigatorのpopメソッドを使うだけで自動で遷移元ファイルと紐付けて戻る画面遷移を実装することができます。

もし画面のWidgetでScaffoldの上にAppBarを設置している場合は左にデフォルトで戻るボタンを表示してくれるのでそれを押しても元の画面に戻れるようになってます。親切設計。

補足:遷移先画面から遷移元画面に戻る時にデータを受け取る

Navigator.popの第2引数を指定することで遷移元画面への戻り値を設定できます。

main.dart
 child: ElevatedButton(
          child: Text('次のページ'),
          onPressed: () async{
            var returnWord = await Navigator.push(  // 戻り値が帰るまで処理を止めておく
                context, MaterialPageRoute(builder: (context) => NextPage()));
            print(returnWord);
          },
        ),
next_page.dart
child: ElevatedButton(
          child: Text('前のページに戻るよ'),
          onPressed: () {
            Navigator.pop(context, '値を戻すよ');
          },
        ),

まず、遷移元画面のonPressedにasyncを付けて非同期処理を可能にさせてNavigator.pushにawaitをつけます。

こうする事で遷移先画面から戻り値が返却されるまで処理を停止させておく事ができます。

戻り値が返却されると、その値がreturnWordに格納されるのでその結果をprintできます。

何も返さないとnullが返ってくるので扱いに気をつけましょう。

おわりに

たった数行書くだけで画面遷移を実装できてしまうのはFlutterの大きな強みだと思いました。

webで画面遷移のルーティングを実装するとなるともっと手間がかかるイメージです。

今回紹介した方法も公式ドキュメントに記載されてるので、もっとよく理解したい人はこっちも読んで見るのがおすすめです。

https://flutter.dev/docs/cookbook/navigation/navigation-basics

思ったより簡単に実装できるので是非実際に動かして体感して自分のものにしてみてください。

おわり

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です