ルーティングライブラリをどうしようかと思ってたら、
go_routerがよさそうなので、試してみたときの備忘録。
Flutter Favoriteにもなっていて、
公式ドキュメントの日本語版もあるよう。
インストール
$ flutter pub add go_router $ flutter pub get
使い方
ルーティングの定義
ルーティングの定義はこんな感じ。
import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'configs/const.dart'; import 'pages/home/home.dart'; Future<void> main() async { WidgetsFlutterBinding.ensureInitialized(); // #を使わないURLパスの形式に設定 GoRouter.setUrlPathStrategy(UrlPathStrategy.path); runApp(const ProviderScope(child: App())); } // Routerの定義。Providerで取得できるようにしておく。 final routerProvider = Provider( (ref) => GoRouter( debugLogDiagnostics: true, routes: [ GoRoute( path: "/", builder: (_, __) => const MyHomePage(title: "HOME"), ) ], ), ); class App extends ConsumerWidget { const App({Key? key}) : super(key: key); // This widget is the root of your application. @override Widget build(BuildContext context, WidgetRef ref) { final router = ref.watch(routerProvider); // routerDelegateとrouteInformationParserに設定 return MaterialApp.router( title: appName, theme: appTheme, routerDelegate: router.routerDelegate, routeInformationParser: router.routeInformationParser, ); } }
サンプルにあるとおり、
階層構造でルーティングを定義したり、
/users/:id
みたいな動的なパスパラメタを受け取ることができる。
final routerProvider = Provider( (ref) => GoRouter( debugLogDiagnostics: true, routes: [ GoRoute( path: '/', builder: (_, __) => const HomePage(), routes: [ GoRoute( path: 'users', builder: (_, __) => const UsersPage(), routes: [ GoRoute( path: ':id', builder: (_, state) => ProviderScope( overrides: [ userIdProvider.overrideWithValue(state.params['id']!) ], child: const UserPage(), ), ), ], ), ], ), ], ), );
・Declarative Routing | go_router
画面遷移
定義したルートへの遷移は、BuildContext
を使ってできる。
// navigate using the GoRouter more easily onTap: () => context.go('/page2')
Linkウィジェットを使った方法でもOK。
Link( uri: Uri.parse('/page2'), builder: (context, followLink) => TextButton( onPressed: followLink, child: const Text('Go to page 2'), ), ),
まえのページへ戻るときは、pop()
でOK。
context.pop();
トップレベルのでリダイレクト(ログイン画面への遷移など)
ログインしてなかったらログイン画面に移動するなど、
全体のリダイレクトもできる。
class App extends StatelessWidget { final loginInfo = LoginInfo(); ... late final _router = GoRouter( routes: [ GoRoute( path: '/', builder: (context, state) => HomeScreen(families: Families.data), ), ..., GoRoute( path: '/login', builder: (context, state) => LoginScreen(), ), ], // redirect to the login page if the user is not logged in redirect: (state) { // if the user is not logged in, they need to login final loggedIn = loginInfo.loggedIn; final loggingIn = state.subloc == '/login'; if (!loggedIn) return loggingIn ? null : '/login'; // if the user is logged in but still on the login page, send them to // the home page if (loggingIn) return '/'; // no need to redirect at all return null; }, ); }
以上!! これでだいぶ楽に(´ω`)