【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

お知らせ

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

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

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

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

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

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

Read More

お知らせ

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

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

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

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

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

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

Read More