MOB-LOG

モブおじの記録 (Programming, 統計・機械学習)

Flutterで遷移のときNavigatorに余計な遷移を残したくない場合、`pop()`→`push()`ではなく、`pushReplacement`を使う。 Navigator.of(context).pop() does not work in Flutter

TL; DR

Flutterで遷移のときNavigatorに余計な遷移を残したくない場合、pop()push()ではなく、pushReplacementを使う。

Navigator.of(context).pushReplacement(MaterialPageRoute())

pop()push()だとでコンテキストのスタックが現在のウィジェットしかないとき(ランディングページとか)、おそらくpop()で空にならずに残ってしまう(詳しくは知らん)。

Navigator.of(context).pushReplacement(MaterialPageRoute(
                builder: (context) {
                  return hogeWidget;
                },
              ));

問題

ログインページだとか、その後もう訪れないようなページに関して(ログイン状態でログインページに再度訪れて余計な操作してほしくない)、以下の様にpop()push()をしていたら、たまに戻るボタンが残っていたりした。

Navigator.of(context).pop()
Navigator.of(context).push(MaterialPageRoute(build:(context) => hogeWidget))

Flutterのbackボタン(scaffold)
↑ こいつが残ってしまう

解決策

なぜかは知らんが、邪魔なので消そうとしていろいろ試していたが、代わりにpushReplacementで何とかなるらしい(https://stackoverflow.com/questions/49707580/flutter-navigator-pop-does-not-work)。

/// ↓じゃあダメ
// Navigator.of(context).pop;
// Navigator.of(context).push(MaterialPageRoute(
//   builder: (context) {
//     return hogeWidget;
//   },
// ));

/// これでよい ↓
Navigator.of(context).pushReplacement(MaterialPageRoute(
                builder: (context) {
                  return hogeWidget;
                },
              ));

そもそも Navigator.of(context).pop()Navigatorが管理するルートのスタックをpopするために使うのではなくて、単純に前のページに戻るために使用されるので(pop()するだけでstackのprevに遷移する)、pop()push()だと毎回戻っている様子で適切ではない(気持ちが悪い。参考:https://docs.flutter.dev/cookbook/navigation/navigation-basics#3-return-to-the-first-route-using-navigatorpop)

なので断然pushReplacementを使用しよう。

学び

  • 特別な理由がない限りNavigator.of(context).pop()を前のページに戻る以外で使用しないこと。
  • Navigatorに現在のページを残したくない場合は、Navigator.of(context).pushReplacement()を使用する。(空のルートスタック(現在のページ以外ない)にpop()してもなにも起きないらしい)

参考