こんにちは、エキサイトでアプリエンジニアをしている岡島です。エキサイトホールディングス Advent Calendar 2024の21日目を担当させていただきます。
今回はgo_routerを触ってみたので、go_routerについて共有していこうと思います。
環境
dependencies: go_router: ^14.6.2
go_routerの特徴
go_routerは、ルーティングのライブラリであり、URLに基づいたナビゲーションのため、ディープリンクを扱いやすいなどの特徴があります。
pub.devのReadmeには次のような特徴があると書かれています。
- テンプレート構文を使用したパス パラメーターとクエリ パラメーターの解析
- 目的地(サブルート)の複数画面の表示
- リダイレクトのサポート
- ShellRouterによる複数のナビゲーターのサポート
- MaterialとCupertinoアプリのサポート
- Navigator APIの後方互換性
go_routerの基本
準備
基本的に必要となることは以下のとおりです。
GoRouterの構成を宣言するMaterialApp.routerやCupertinoApp.routerを使用して準備をする
GoRouterの構成を宣言する
以下の例のようにそれぞれの画面を宣言していきます。
最低限必要なものはpathとbuilderです。
final router = GoRouter( routes: [ GoRoute( path: '/', builder: (BuildContext context, GoRouterState state) { return const HomeScreen(); }, ), GoRoute( path: 'screen1', builder: (BuildContext context, GoRouterState state) { return const Screen1(); }, ), ], );
はじめに開く画面を指定する場合はinitialLocationでパスを指定します。
final router = GoRouter( initialLocation: '/', routes: [ // GoRoute()の宣言 ], );
他にもdebugLogDiagnostics: true, とするとログが出力されるようになります。
MaterialApp.routerやCupertinoApp.routerを使用して準備をする
アプリでgo_routerを利用するには、MaterialApp.routerやCupertinoApp.router 使用し、routerConfig に宣言したGoRouterの構成オブジェクトを設定します。
void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp.router( routerConfig: router, ); } }
以上で準備が完了です。
画面遷移の方法
ここまでの準備で、go_routerを利用すると、画面遷移の時にcontext.go()を用いて遷移することができます。下のように書くと、TextButtonをタップしてScreen1に遷移することができます。
return TextButton( child: const Text('Screen1'), onPressed: () => context.go('/screen1'), );
他にもNavigator.of(context).push()やNavigator.of(context).pop()の代わりにcontext.push()やcontext.pop()が利用できます。
go_routerではBuildContextのナビゲーションに拡張関数を定義しています。
extension GoRouterHelper on BuildContext
この拡張関数のおかげで、context.go()やcontext.pop()というようにcontext.〇〇で遷移することができるようになっています。
名前付きルートを使用する
GoRouteに一意の名前をつけることができます。設定するには宣言時にnameのパラメータを追加するだけです。
GoRoute( name: 'myPage', path: /* ... */, builder: /* ... */, ),
遷移する時はgoNamedを用います。
TextButton(
onPressed: () {
context.goNamed('myPage');
},
child: const Text('myPageへ遷移'),
),
こうすることで以下のメリットがあります。
- パスの変更に柔軟になる
- nameを用いて遷移するので、パスの変更があっても一括で変更できます。複数の画面でパスを指定して遷移していた場合は、それぞれの箇所でパスを変更する必要があります。
OSごとにテーマを設定する方法
準備の段階で、MaterialApp.routerやCupertinoApp.routerを使用していましたが、PlatformApp.routerを用いるとMaterialやCupertinoデザインを区別することができます。
PlatformApp.routerを用いるにはflutter_platform_widgetsをインストールする必要があるのでご注意下さい。
https://pub.dev/packages/flutter_platform_widgets
AndroidはMaterial系のデザインに寄せてテーマを設定するなどということができます。
return PlatformApp.router( routerConfig: router, material: (_, __) => MaterialAppRouterData( theme: ThemeData( primaryColor: Colors.red, ), ), cupertino: (_, __) => CupertinoAppRouterData( theme: const CupertinoThemeData( primaryColor: Colors.blue, ), ), );
最後に
go_routerを用いることで、URLベースのナビゲーションが可能とwebに似た操作ができるようになりました。またディープリンクに対応しやすくなるのも利点の一つかと思いました。
最後まで読んでいただきありがとうございました!