【Flutter】もうnamedRouteは使わない!僕が全力で勧めたいルーティング方法をサンプル付きで解説してみた

Dart

概要

どうも、@daiki1003です!

皆さん、ページ間の遷移はどんな方式でやっていますか?

Navigator2.0ですか?
…すごい、僕に教えてください🙇‍♂️笑

え、まだpushNamedを使っている?
僕にもそんな時期がありました。
今日はそんな皆さんにおすすめのルーティング方法をお教えしたいと思います!

pushNamed時代に感じていた問題意識

以前は、pushNamedを使っていましたが、
その時に以下の3つの問題意識を抱えていました。

1. ページの追加が面倒

ページを追加するたびに、routeNameを定義して、
app.dartに移動して、routesに追加して…とやるのが大変億劫でした。

2. ページを表示するのに必須パラメータが何かを覚えていないといけない

引数なしで遷移出来るページもありますが、引数が必要なページもありますよね?
そんな時にそのページに何を渡すか全部覚えてますか?
ページ設計者なら分かるかもしれませんが、新しく入ってきた人に分かりますか?

また、それをModalRouteから引き出す際に暗黙的なキャストが必要です。
もし、渡す側だけ型を変え、受け取り側を変え忘れていれば正しく処理出来なくなります。

3. Navigatorを作った際に、onGenerateRouteで再定義しなければいけない

BottomNavigationBarを用いたアプリで
タブを画面下部に残したまま遷移したい場合、Navigatorをタブ毎に別途作成する必要があります。

ここで、pushNamedを使っていると、各タブ毎のNavigatorで遷移するであろう全てのページを
onGenerateRouteに定義する必要がありますが、これがまた大変です…。

MaterialAppにも設定しているのに、ここでも設定しなければいけないのか…
となりました。

そこで…!
今回紹介するルーティング方法です。

※全コードは下記gistに載せてあります!

僕が全力でお勧めしたいルーティング方法

それがこちらです。

class SampleWithPush extends StatelessWidget {
  static Route<dynamic> route() {
    return MaterialPageRoute<dynamic>(
      builder: (_) => SampleWithPush(),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Anything();
  }
}

遷移させる側のコードはこちら。

Navigator.of(context).push<dynamic>(
 SampleWithPush.route(),
)

🎉これだけです!!!🎉
もう、routesへの登録は必要ありません。

作成したページに、staticRouteを返すメソッドを作成してあげるだけ。
簡単じゃないですか?
これで1. ページの追加が面倒の問題は解消されましたね!

と同時に、pushNamedではなくpushを使うため、
onGenerateRouteも参照されません。
よって、3. Navigatorを作った際に、onGenerateRouteで再定義しなければいけないも解消されました!

引数を付けたルーティングはどうすれば良いの?

class SampleWithArg extends StatelessWidget {
  static Route<dynamic> route({
    @required int someId,
  }) {
    return MaterialPageRoute<dynamic>(
      builder: (_) => SampleWithArg(),
      settings: RouteSettings(arguments: someId),
    );
  }

  @override
  Widget build(BuildContext context) {
    final someId = ModalRoute.of(context).settings.arguments;
    return SafeArea(
      child: Scaffold(
        appBar: AppBar(),
        body: Center(
          child: Text(someId.toString()),
        ),
      ),
    );
  }
}

この様にrouteメソッドに引数を付けて定義し、
settingsに渡すだけです。
使う側(主にbuildメソッド)は、いつもの様にModalRoute.of(context).settings.argumentsで取得します。

遷移させる側のコードはこちら。

Navigator.of(context).push<dynamic>(
  SampleWithArg.route(someId: 1),
)

@requiredなため、仮にsomeIdを渡さないと、エラーは出ないまでも警告を出してくれます。
仮に渡さなければいけない引数を忘れていたとしても、警告で教えてくれるので
忘れる心配はほぼ0です。

Navigator.of(context).push<dynamic>(
  SampleWithArg.route(), // warning!
)

これで、2. ページを表示するのに必須パラメータが何かを覚えていないといけないも解消されました!

いかがでしょうか?
しばらくこのルーティングを使っていますが、特に困ったシチュエーションは今のところありません。

よければ使ってみてくださいね!

誰かのお役に立てば。

Twitterフォローお願いします

「次回以降も記事を読んでみたい!」
「この辺分からなかったから質問したい!」

そんな時は、是非@daiki1003のフォローお願いします♪

また、記事がとても役に立ったと思う人は
コーヒーを奢っていただけると非常に嬉しいです!

コメント

タイトルとURLをコピーしました