【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

お知らせ

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

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

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

Read More
U30可茂ITインターンハッカソン

U30可茂ITインターンハッカソン

12月28,29日開催。2日間でアプリ開発の企画から完成までを目指す!U30可茂ITインターンハッカソンを開催します。

Read More

タグ

Flutter (113)初心者向け (28)イベント (18)Google Apps Script (15)Nextjs (12)可茂IT塾 (9)Firebase (7)riverpod (6)React (6)ChatGPT (5)vscode (5)デザイン (5)新卒 (4)就活 (4)Figma (4)Dart (4)JavaScript (4)お知らせ (4)FlutterWeb (3)Prisma (3)NestJS (3)Slack (3)TypeScript (3)ワーケーション (3)インターン (3)設計 (2)線型計画法 (2)事例 (2)Git (2)Image (2)File (2)Material Design (2)画像 (2)iOS (2)アプリ開発 (2)React Hooks (2)tailwindcss (2)社会人 (2)大学生 (2)RSS (1)Google (1)Web (1)CodeRunner (1)個人開発 (1)Android (1)Unity (1)WebView (1)Twitter (1)フルリモート (1)TextScaler (1)textScaleFactor (1)学生向け (1)supabase (1)Java (1)Spring Boot (1)shell script (1)正規表現 (1)パワーポイント (1)趣味 (1)モンスターボール (1)CSS (1)SCSS (1)Cupertino (1)ListView (1)就活浪人 (1)既卒 (1)保守性 (1)iPad (1)シェアハウス (1)スクレイピング (1)PageView (1)画面遷移 (1)flutter_hooks (1)Gmail (1)GoogleWorkspace (1)ShaderMask (1)google map (1)Google Places API (1)GCPコンソール (1)Google_ML_Kit (1)Vercel (1)Google Domains (1)DeepLeaning (1)深層学習 (1)Google Colab (1)コード生成 (1)GitHub Copilot (1)オンラインオフィス (1)オブジェクト指向 (1)クラスの継承 (1)ポリモーフィズム (1)LINE (1)Bitcoin (1)bitFlyer (1)コミュニティー (1)文系エンジニア (1)Freezed (1)ヒーター (1)作業効率 (1) (1)Flutter実践開発 (1) (1)permission_handler (1)flutter_local_notifications (1)markdown (1)GlobalKey (1)ValueKey (1)Key (1)アイコン (1)go_router (1)debug (1)datetime_picker (1)Apple Store Connect (1)FlutterGen (1)デバッグ (1)Widget Inspector (1)VRChat (1)API (1)検索機能 (1)Shader (1)Navigator (1)メール送信 (1)FlutterFlow (1)Firebase App Distribution (1)Fastlane (1)Dio (1)CustomClipper (1)ClipPath (1)カスタム認証 (1)アニメーション (1)Arduino (1)ESP32 (1)経験談 (1)フリーランス (1)mac (1)csv (1)docker (1)GithubActions (1)Dialog (1)BI (1)LifeHack (1)ショートカット (1)Chrome (1)高校生 (1)キャリア教育 (1)非同期処理 (1)生体認証 (1)BackdropFilter (1)レビュー (1)getAuth (1)Algolia (1)コンサルティング (1)Symbol (1)

お知らせ

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

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

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

Read More
U30可茂ITインターンハッカソン

U30可茂ITインターンハッカソン

12月28,29日開催。2日間でアプリ開発の企画から完成までを目指す!U30可茂ITインターンハッカソンを開催します。

Read More