Flutterの画面遷移を完全マスター!Navigatorの使い方を基礎から解説

Flutterでアプリを作る時、複数の画面を行き来できるようにするのは必須の機能だよね。例えば、ホーム画面から詳細画面に移動したり、設定画面を開いたりする、といったことだ。

この画面遷移を実現してくれるのがNavigatorというWidgetなんだ。
Navigatorは画面をスタック構造で管理していて、まるで本を積み重ねるように画面を重ねていく仕組みになっているよ。

スタック構造って聞くと難しそうだけど、実はとってもシンプル。

一番上に積まれた本(画面)が、今ユーザーが見ている画面ってわけだね。
新しい画面を開くときは上に積んで、戻るときは一番上の本を取り除く。

これだけ!

スポンサーリンク

画面遷移の基本メソッド:pushとpop

Navigator.push() – 新しい画面に進む

新しい画面に遷移するときはNavigator.push()メソッドを使うんだ。使い方はこんな感じだよ。

Navigator.push(
  context,
  MaterialPageRoute(builder: (context) => NextPage()),
);

この3行のコードで、NextPageという画面に遷移できる。簡単でしょ?

コードの内訳を説明すると:

  • context:今どの画面にいるかという位置情報。おまじないとして覚えておけばOK
  • MaterialPageRoute:画面遷移時のアニメーションを設定するクラス。マテリアルデザインのアニメーションが使われる
  • builder:実際に表示する画面(Widget)を指定する部分

Navigator.pop() – 前の画面に戻る

前の画面に戻りたいときはNavigator.pop()を使おう。

Navigator.pop(context);

たったこれだけ。スタックの一番上の画面を取り除いて、その下にあった画面(つまり前の画面)が表示されるんだ。

実は、Scaffoldを使っている場合は自動的に「戻るボタン」がAppBarに表示されるから、わざわざpopを書かなくても大丈夫な場合が多いよ。Androidの端末なら、端末の戻るボタンを押すだけでも同じ動作になる。

実際のコード例で確認してみよう

2つの画面を行き来する簡単なアプリを作ってみるね。

import 'package:flutter/material.dart';

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

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

// 最初の画面
class FirstPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('最初の画面'),
      ),
      body: Center(
        child: ElevatedButton(
          child: Text('次の画面へ'),
          onPressed: () {
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => SecondPage()),
            );
          },
        ),
      ),
    );
  }
}

// 2番目の画面
class SecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('2番目の画面'),
      ),
      body: Center(
        child: ElevatedButton(
          child: Text('戻る'),
          onPressed: () {
            Navigator.pop(context);
          },
        ),
      ),
    );
  }
}

このコードを実行すると、ボタンを押して画面を行き来できるアプリが完成するよ!

名前付きルート(Named Routes)を使う方法

もう一つの画面遷移の方法として、名前付きルートという仕組みがあるんだ。あらかじめ画面に名前をつけておいて、その名前で遷移する方法だね。

名前付きルートの設定方法

まずはMaterialAppで各画面に名前を設定するよ。

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      initialRoute: '/',  // 最初に表示する画面
      routes: {
        '/': (context) => HomePage(),
        '/detail': (context) => DetailPage(),
        '/settings': (context) => SettingsPage(),
      },
    );
  }
}

名前付きルートで遷移する

設定した名前を使って遷移するときはNavigator.pushNamed()を使うんだ。

Navigator.pushNamed(context, '/detail');

こっちの方がシンプルでしょ?ただし、パスが文字列なので打ち間違いに注意が必要だよ。

便利な画面遷移メソッド

基本のpushとpop以外にも、便利なメソッドがいくつかあるから紹介するね。

Navigator.pushReplacement() – 画面を置き換える

今の画面を新しい画面に置き換えたいときに使うよ。例えば、ログイン画面からホーム画面に遷移するときなんかに便利だね。

Navigator.pushReplacement(
  context,
  MaterialPageRoute(builder: (context) => HomePage()),
);

普通のpushとの違いは、前の画面がスタックから削除されること。だから、ホーム画面で戻るボタンを押してもログイン画面には戻らないんだ。

名前付きルートでも同じことができるよ。

Navigator.pushReplacementNamed(context, '/home');

Navigator.pushAndRemoveUntil() – 指定した画面まで削除

複数の画面を一気に削除して、特定の画面まで戻りたいときに使うメソッドだよ。

Navigator.pushAndRemoveUntil(
  context,
  MaterialPageRoute(builder: (context) => HomePage()),
  (route) => false,  // falseにすると全ての画面を削除
);

ログアウトして最初の画面に戻る、といった場面で活躍するね。

Navigator.popUntil() – 指定した画面まで戻る

特定の画面まで一気に戻りたいときはこれ。

Navigator.popUntil(context, (route) => route.isFirst);

この例では、最初の画面まで一気に戻ることができるんだ。

画面間でデータを受け渡しする方法

画面遷移するときに、データを次の画面に渡したいことってよくあるよね。例えば、リスト画面から詳細画面に移動するとき、どの項目が選ばれたかを伝える必要があるでしょ。

データを渡す側

次の画面にデータを渡すには、画面のコンストラクタを使うのが簡単だよ。

// データを受け取る側の画面
class DetailPage extends StatelessWidget {
  final String itemName;

  DetailPage({required this.itemName});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(itemName)),
      body: Center(child: Text('選択された項目: $itemName')),
    );
  }
}

// データを渡す側
Navigator.push(
  context,
  MaterialPageRoute(
    builder: (context) => DetailPage(itemName: '商品A'),
  ),
);

データを受け取る(戻り値)

逆に、遷移先の画面からデータを返してもらうこともできるんだ。

// データを返す側(遷移先の画面)
Navigator.pop(context, '選択結果');

// データを受け取る側(元の画面)
final result = await Navigator.push(
  context,
  MaterialPageRoute(builder: (context) => SelectionPage()),
);
print(result);  // '選択結果'が表示される

awaitを使うことで、画面から戻ってくるまで待つことができるんだね。

iOS風のアニメーションを使いたいとき

Flutterでは、iOS風のアニメーションも簡単に使えるよ。MaterialPageRouteの代わりにCupertinoPageRouteを使うだけ。

Navigator.push(
  context,
  CupertinoPageRoute(builder: (context) => NextPage()),
);

これで、iPhoneアプリっぽい画面遷移アニメーションになるんだ。

よくあるつまずきポイントと対処法

contextが取得できない

「contextって何?」って混乱することがあるかもしれないけど、これはWidgetの位置情報を表すものなんだ。基本的には、buildメソッドの引数として渡ってくるから、それをそのまま使えばOK。

戻るボタンを押しても反応しない

Scaffoldを使っていれば、自動的に戻るボタンが表示されて機能するよ。もし動かない場合は、Scaffoldが正しく配置されているか確認してみよう。

名前付きルートで画面が見つからない

ルート名の打ち間違いが多いから、注意深くチェックしてね。スラッシュ(/)を忘れていないかも確認しよう。

Navigator 2.0について

2020年末から「Navigator 2.0」という新しい画面遷移の仕組みも登場しているんだ。

これはWebアプリやURLベースの遷移に対応するための、より高機能な仕組みだよ。

ただし、シンプルなアプリなら今回紹介した従来の方法(Navigator 1.0と呼ばれる)で十分。複雑なディープリンクやWeb対応が必要になったら、go_routerなどのパッケージを検討するといいね。

まとめ:画面遷移はこれでバッチリ!

Flutterの画面遷移は、Navigatorを使えば驚くほど簡単に実装できるんだ。

基本を押さえよう:

  • Navigator.push()で新しい画面に進む
  • Navigator.pop()で前の画面に戻る
  • スタック構造で画面が管理されている
  • 名前付きルートを使うとコードがスッキリする

応用テクニック:

  • pushReplacement()で画面を置き換える
  • pushAndRemoveUntil()で複数画面を一気に削除
  • コンストラクタでデータを渡す
  • awaitpop()で戻り値を受け取る

コメント

タイトルとURLをコピーしました