flutterの画面遷移(ルーティング)でnavigatorとgorouterどちらを使うか
はじめに
flutterにおける画面遷移でnavigatorとgorouterのどちらを採用するか悩みました。
簡単なアプリでNavigator1.0、比較的複雑なアプリでgo_routerを使ってみたので実際のコードや参考を含めて記載しておきます。
バージョン
Flutter: 3.16.8
Dart: 3.2.5
go_router: 13.2.0
結論
- 小規模な個人開発やテスト用のローカルリポジトリであればNavigator 1.0
- WebViewを使用するのであればNavigator 2.0
- チーム開発やViewの多いアプリではgo_router
Navigator 1.0のメリット
- コードが端的で書きやすい
- 定義されているclassのため、パッケージを入れる必要がない
- UIや機能のテストに便利
Navigator 2.0のメリット
- 静的、動的な細かい遷移を指定できる。
- 定義されているclassのため、パッケージを入れる必要がない
go_routerのメリット
- modelが1つあれば、各Viewページにて処理を簡単に実装できる
- 実装内容としては、Navigator 2.0の仕様を踏襲
Navigator
Navigatorの使い方
1. 新しい画面に遷移する(Push)
画面Aから画面Bへ遷移する場合、Navigator.pushメソッドを使用します。この方法は、新しい画面を画面スタックの上に積む操作に相当します。
Navigator.push(
context,
MaterialPageRoute(builder: (context) => NewScreen()), // NewScreenは遷移先の画面クラス
);
2. 画面を戻る(Pop)
画面Bから画面Aに戻る場合(または現在の画面を閉じる場合)、Navigator.popメソッドを使用します。
Navigator.pop(context);
3. 名前付きルートを使用する
Flutterでは、画面遷移を管理するために名前付きルート(Named Routes)を使用することができます。この方法では、アプリケーションのMaterialAppウィジェット内でルートを定義し、画面遷移時にその名前を指定します。
MaterialAppウィジェットでルートを定義する:
MaterialApp(
// 名前付きルートの定義
routes: {
'/': (context) => HomeScreen(),
'/new': (context) => NewScreen(),
},
);
名前付きルートを使用して新しい画面に遷移する:
Navigator.pushNamed(context, '/new');
4. 引数を渡しながらの画面遷移
画面遷移する際に、次の画面にデータを渡すこともできます。MaterialPageRouteのbuilderプロパティに渡す関数で、データを引数にして新しい画面のインスタンスを作成します。
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => NewScreen(data: "データ"),
),
);
go_router
go_routerの使い方
flutterのgo_routerで同様のことを書き直します。
1.まずはgo_routerパッケージをインポートします。
flutter pub add go_router
import 'package:go_router/go_router.dart';
Routerオブジェクトを生成します。
final router = Router();
ルートパス"/"にハンドラを登録します。
router.define(
'/',
handler: (BuildContext context, GoRouterState state) {
return Text('Welcome');
}
);
パスパラメーターを指定したルーティングです。
router.define(
'/products/:key',
handler: (BuildContext context, GoRouterState state) {
final key = state.params['key'];
return Text('The key is $key');
}
);
アプリ起動時にRouterを設定します。
void main() {
runApp(
MaterialApp.router(
router: router
)
);
}
go_routerを使った複数ページのルーティング
ログインやBottoNavigationbarと組み合わせた際にやったこと
実際のアプリでの実装の際は、ログインやユーザーの動き次第での画面遷移、BottomNavgationbar、設定ページの中にネストされたページを一挙に実装した場合、以下の処理が必要になりました。
- createRouterメソッドでGoRouterインスタンスを作成し、各ページルートを設定
- ShellRouteでBottomNavWidgetをラップして子ルートとしてページを設定
- 各ページ用のGoRouteを定義し、Builderでそれぞれのウィジェットを定義
- AuthInfoModelからユーザー情報を見て初期ルートを決定
- ログイン状態に応じてリダイレクト設定
- 設定ページの下位ルートも定義
以下に1例として設定ページの中にネストしたページを入れて遷移させる場合のgo_router部分を抜粋します。
基本的な設定を行なった後、設定ページのルートを定義する
例えば、以下のように設定ページに入れる予定の3つのルート(画面遷移先)を書きます。
bottomnavigationbarにあるsetting(設定ページ)から遷移したいルートになります。
1.以下のようにそれぞれの遷移先ページを定義する(以下はプライバシーポリシーページ)
GoRoute privacyPolicyRoute() {
return GoRoute(
path: 'privacy_policy',
builder: (context, state) {
return const PrivacyPolicyPage();
},
);
}
2.設定ページからどこへ遷移するか定義する
GoRoute settingRoute() {
return GoRoute(
path: '/setting',
routes: [
languageSettingRoute(),//言語設定
aboutAppRoute(),//アプリについての説明
deleteAuthRoute(),//アカウント削除
],
builder: (context, state) {
return const SettingPage();//遷移先ページから設定ページに戻ることができる
},
);
}
3.さらにアプリについての説明ページから他ページへの遷移も定義する
GoRoute aboutAppRoute() {
return GoRoute(
path: 'about_app',
routes: [
kiyakuRoute(),
termsOfServiceRoute(),
privacyPolicyRoute(),
developerInfoRoute(),
],
builder: (context, state) {
return const AboutAppPage();
},
);
}
今回参考にさせていただいた記事を以下に記載します。
読んでいただきありがとうございました。
参考
Discussion