LoginSignup
5
2

More than 1 year has passed since last update.

FlutterのNavigator1.0を完全に理解した気になっていたので再入門した

Last updated at Posted at 2021-12-24

何でまとめようと思ったのか

携わっているプロジェクトはFlutterが正式リリースされる前から存在していたので、
年を重ねて大きくなり、遷移も複雑になってきていた。
発端は、いつからかログイン画面が複数回Pushされているような挙動が起きたり、ダイアログ表示の時に背景がだんだん黒くなってきたりといった現象が起き始めていた。(チームでうまくNavigatorが扱えてなかった。)

メンバーの認識も、まちまちで「あれってルートを置き換えてくれるだけの遷移方法だよね?」、「てっきり、置き換えると同時に他も破棄してくれるもんだと思っていた」とバラバラだった。

基本的なところにはなるが、今一度見直してみた。

画面遷移の種類

※AndroidだろうがiOSだろうがFlutterだろうが
画面遷移に関してはHistoryというものが存在し、
その形式はStack構造になっている。

push() & pushNamed()

Stackの一番上に、指定したルートを追加する
スクリーンショット 2021-12-23 163322.png

スクリーンショット 2021-12-23 163408.png

pop()

Stackの一番上にあるルートを削除する
スクリーンショット 2021-12-23 164835.png

popAndPushNamed() & pushReplacementNamed()

Stackの一番上にあるルートを削除し、指定したルートを新規にStackの一番上に追加する。
挙動は一緒だが違うのは、削除されるルートのアニメーションの違いにある。

どんな時に使う?

使用ケース的には、遷移先の画面から前の画面に戻したくないとき。
主にログイン画面からの遷移とかスプラッシュ画面からの遷移とかに使う。

before

スクリーンショット 2021-12-23 174512.png

after

スクリーンショット 2021-12-23 174836.png

before

スクリーンショット 2021-12-23 174655.png

after

スクリーンショット 2021-12-23 174710.png

popAndPushNamed:

Stackからルートが削除されるとき、popアニメーションが行われる
ezgif-3-05f5126aaa.gif

pushReplacementNamed:

Stackからルートが削除されるとき、popアニメーションが行われない
ezgif-3-ca25755147.gif

pushNamedAndRemoveUntil()

ルートを指定しないとPushされたルートより前にあるルートを全部破棄する。

Navigator.of(context).pushNamedAndRemoveUntil('/login', (Route<dynamic> route) => false);

スクリーンショット 2021-12-23 184455.png

第2引数にルートを指定すると、指定されたルートより上に存在するルートをすべて削除し、残ったルートの上にルートを追加する。

Navigator.of(context).pushNamedAndRemoveUntil('/page5', ModalRoute.withName('/page1'));

スクリーンショット 2021-12-23 191322.png

popUntil()

指定されたルートより上に溜まっているルートをすべてStackから削除する。

スクリーンショット 2021-12-23 230534.png

遷移時の値の受け渡し

だいたい、Argumentsクラス作って渡すことが多いと思う。

@immutable
class PageArguments{
  final Customer customer;
  final int index;

  PageArguments({
    @required this.customer,
    @required this.index,
  });
}
Navigator.of(context).pushReplacementNamed(
  '/page2',
  arguments: PageArguments(
    customer: customerState.profile 
    index: pageState.pageList
        .indexWhere((element) => element == PageType.normal),
  ),
);
5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2