【Flutter】 Navigatorメソッドの違いを知る

image

Version

  • Flutter 2.10.1
  • Dart 2.16.1

はじめに

Flutter画面遷移をするために頻出するNavigatorクラスですが、初心者のためにまとめてみました。 コード全文はこちらになります。

今回の画面遷移のイメージ

Navigatorデモ

クラス作成

class ButtonWidget

メソッドの違いがわかるようにButtonWidgetクラスを作成。 このクラスを使って各Pageのボタンを作成できるようにします。

import 'package:flutter/material.dart';
import 'package:flutter_basic_navigator/pages/second_text_input_page.dart';
import 'package:flutter_basic_navigator/widgets/sample_dialog.dart';

class ButtonWidget extends StatelessWidget {
  ButtonWidget(
      {Key? key,
      required String this.pushOrPop,
      Widget? this.widget,
      required String this.description})
      : super(key: key);
  final String pushOrPop;
  final Widget? widget;
  final String description;

  
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          ElevatedButton(
              onPressed: () async {
                if (pushOrPop == 'pushReplacement' && widget != null) {
                  Navigator.of(context).pushReplacement(
                      MaterialPageRoute(builder: (context) => widget!));
                }
                if (pushOrPop == 'push' && widget != null) {
                  Navigator.of(context)
                      .push(MaterialPageRoute(builder: (context) => widget!));
                }
                if (pushOrPop == 'push-showDialog' && widget != null) {
                  await Navigator.of(context)
                      .push(MaterialPageRoute(builder: (context) => widget!));
                  showDialog(
                    context: context,
                    barrierDismissible: false,
                    builder: (context) => SampleDialog(
                      contentText: 'FirstPageに戻ります',
                    ),
                  );
                }
                if (pushOrPop == 'push-shoDialog-text' && widget != null) {
                  final result = await Navigator.of(context).push(
                    MaterialPageRoute(
                      builder: (context) {
                        return SecondTextInputPage();
                      },
                    ),
                  );
                  if (result != null) {
                    final contentText = 'result: "${result}" ';
                    showDialog(
                      context: context,
                      barrierDismissible: false,
                      builder: (context) {
                        return SampleDialog(
                          contentText: contentText,
                        );
                      },
                    );
                  }
                }
                if (pushOrPop == 'pop') {
                  Navigator.of(context).pop();
                }
                if (pushOrPop == 'canPop') {
                  print(Navigator.of(context).canPop());
                }
                if (pushOrPop == 'popUntil') {
                  Navigator.of(context).popUntil((route) => route.isFirst);
                }
                if (pushOrPop == 'pushAndRemoveUntil') {
                  Navigator.of(context)
                      .push(MaterialPageRoute(builder: (context) => widget!));
                  Navigator.of(context).pushAndRemoveUntil(
                      MaterialPageRoute(builder: (context) => widget!),
                      (_) => false);
                }
              },
              child: widget != null
                  ? Text('$pushOrPop => ${widget.toString()}()')
                  : Text('$pushOrPop')),
          Text(description),
        ],
      ),
    );
  }
}

メソッドの説明

Navigatorデモ

pushReplacement

Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (context) => widget!));
指定した画面(widget!)へ遷移します。push時にroute画面を消してしまうので、popできなくなります。
SplashPageやLogInPageからの遷移などで使います。

canPop

Navigator.of(context).canPop()
bool値を返します。popできる=true、popできない=false。

pop

Navigator.of(context).pop();
元の画面に戻ります。
*ここではpopできず画面は真っ黒になります。その場合は再起動します。

Navigatorデモ

push

Navigator.of(context).push(MaterialPageRoute(builder: (context) => widget!));
普通のPushです。指定した画面に遷移します。

push-showDialog

pushメソッドの後に処理するコードを書いておくと、popにより戻った直後に処理を実行します。 pushメソッドの前にawaitキーワードを書き、コールバックの先頭にasyncキーワードを書きます。
このコードでは、pop直後にshowDialogメソッドが実行されます。

await Navigator.of(context)
                      .push(MaterialPageRoute(builder: (context) => widget!));
                  showDialog(
                    context: context,
                    barrierDismissible: false,
                    builder: (context) => SampleDialog(
                      contentText: 'FirstPageに戻ります',
                    ),
                  );

push-showDialog-text

上記push-showDialogと同様です。
SecondTextInputPageで入力した文字をshowDialogで表示します。

final result = await Navigator.of(context).push(
                    MaterialPageRoute(
                      builder: (context) {
                        return SecondTextInputPage();
                      },
                    ),
                  );
                  if (result != null) {
                    final contentText = 'result: "${result}" ';
                    showDialog(
                      context: context,
                      barrierDismissible: false,
                      builder: (context) {
                        return SampleDialog(
                          contentText: contentText,
                        );
                      },
                    );

Navigatorデモ

popUntil

Navigator.of(context).popUntil((route) => route.isFirst);
route.isFirst画面まで戻リます。このアプリでは、FirstPageに戻ります。

pushAndRemoveUntil

Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (context) => widget!),(_) => false);
条件(SplashPage)に一致するまでスタックから画面を取り除いていきます。その後画面をpushします。

まとめ

以上、Navigatorメソッドまとめでした。参考になれば幸いです。

参考:https://qiita.com/granoeste/items/19c119ffc36a016e6223

お知らせ

3月19日開催のアプリ開発講座の参加者募集中!!

3月19日開催のアプリ開発講座の参加者募集中!!

3月19日にアプリ開発講座を開催します!会場は岐阜県美濃加茂市のコワーキングスペース「こやぁね」です。興味のある方は是非ご参加ください!

Read More
可茂IT塾ではFlutterインターンを募集しています!

可茂IT塾ではFlutterインターンを募集しています!

可茂IT塾ではFlutterインターンを募集しています!可茂IT塾のエンジニアの判断で、一定以上のスキルをを習得した方には有給でのインターンも受け入れています。

Read More

タグ

Flutter (70)初心者向け (22)イベント (15)Nextjs (8)Google Apps Script (7)可茂IT塾 (6)Firebase (6)React (5)新卒 (3)就活 (3)給与支払報告書 (3)riverpod (3)Dart (3)JavaScript (3)TypeScript (3)インターン (3)FlutterWeb (2)画像 (2)アプリ開発 (2)React Hooks (2)tailwindcss (2)ワーケーション (2)社会人 (2)大学生 (2)お知らせ (2)webfeed (1)RSS (1)CodeRunner (1)VSCode (1)個人開発 (1)設計 (1)フルリモート (1)学生向け (1)Java (1)Spring Boot (1)エンジニア (1)DeviceOrientation (1)正規表現 (1)神楽 (1)趣味紹介 (1)プログラミングだけではない可茂IT塾のメンバー (1)線型計画法 (1)事例 (1)PreferredSize (1)マテリアルデザイン (1)Material (1)クパチーノデザイン (1)Cupertino (1)ListView (1)就活浪人 (1)既卒 (1)保守性 (1)シェアハウス (1)スクレイピング (1)Gmail (1)Googleグループ (1)GoogleWorkspace (1)ShaderMask (1)google map (1)Google Places API (1)Vercel (1)Google Domains (1)branch (1)Git (1)オンラインオフィス (1)Freezed (1)アイコン (1)Apple Store Connect (1)FlutterGen (1)検索機能 (1)Navigator (1)メール送信 (1)カスタム認証 (1)アニメーション (1)FloatingActionButton (1)Arduino (1)ESP32 (1)経験談 (1)フリーランス (1)Dialog (1)Figma (1)デザイン (1)Slack (1)BI (1)非同期処理 (1)BackdropFilter (1)iOS (1)レビュー (1)getAuth (1)匿名 (1)Algolia (1)chakra-ui (1)コンサルティング (1)Symbol (1)reactive_forms (1)

お知らせ

3月19日開催のアプリ開発講座の参加者募集中!!

3月19日開催のアプリ開発講座の参加者募集中!!

3月19日にアプリ開発講座を開催します!会場は岐阜県美濃加茂市のコワーキングスペース「こやぁね」です。興味のある方は是非ご参加ください!

Read More
可茂IT塾ではFlutterインターンを募集しています!

可茂IT塾ではFlutterインターンを募集しています!

可茂IT塾ではFlutterインターンを募集しています!可茂IT塾のエンジニアの判断で、一定以上のスキルをを習得した方には有給でのインターンも受け入れています。

Read More