ルーティングとナビゲーション
Flutterルーティングとナビゲーション完全ガイド
Section titled “Flutterルーティングとナビゲーション完全ガイド”Flutterでの画面遷移とルーティングの実装方法を、基本的な方法から高度なパターンまで詳しく解説します。
1. 基本的なナビゲーション
Section titled “1. 基本的なナビゲーション”Navigator.push/pop
Section titled “Navigator.push/pop”// 画面遷移Navigator.push( context, MaterialPageRoute( builder: (context) => SecondScreen(), ),);
// 前の画面に戻るNavigator.pop(context);
// 戻り値を返すNavigator.pop(context, '戻り値');名前付きルーティング
Section titled “名前付きルーティング”// MaterialAppでルートを定義MaterialApp( initialRoute: '/', routes: { '/': (context) => HomeScreen(), '/second': (context) => SecondScreen(), '/third': (context) => ThirdScreen(), },);
// 画面遷移Navigator.pushNamed(context, '/second');
// 戻り値を受け取るfinal result = await Navigator.pushNamed(context, '/second');2. go_routerを使用したルーティング
Section titled “2. go_routerを使用したルーティング”pubspec.yamlへの追加
Section titled “pubspec.yamlへの追加”dependencies: go_router: ^12.0.0基本的な設定
Section titled “基本的な設定”import 'package:go_router/go_router.dart';
final router = GoRouter( initialLocation: '/', routes: [ GoRoute( path: '/', builder: (context, state) => HomeScreen(), ), GoRoute( path: '/second', builder: (context, state) => SecondScreen(), ), GoRoute( path: '/user/:id', builder: (context, state) { final id = state.pathParameters['id']!; return UserScreen(userId: id); }, ), ],);
// main.dartvoid main() { runApp(MyApp());}
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp.router( routerConfig: router, ); }}// 画面遷移context.go('/second');
// 戻るcontext.pop();
// 戻り値を返すcontext.pop('戻り値');クエリパラメータ
Section titled “クエリパラメータ”GoRoute( path: '/search', builder: (context, state) { final query = state.uri.queryParameters['q'] ?? ''; return SearchScreen(query: query); },);
// 使用例context.go('/search?q=flutter');3. ネストされたルーティング
Section titled “3. ネストされたルーティング”final router = GoRouter( routes: [ GoRoute( path: '/', builder: (context, state) => HomeScreen(), routes: [ GoRoute( path: 'profile', builder: (context, state) => ProfileScreen(), routes: [ GoRoute( path: 'settings', builder: (context, state) => SettingsScreen(), ), ], ), ], ), ],);4. リダイレクトとガード
Section titled “4. リダイレクトとガード”final router = GoRouter( redirect: (context, state) { final isLoggedIn = AuthService.isLoggedIn(); final isGoingToLogin = state.matchedLocation == '/login';
if (!isLoggedIn && !isGoingToLogin) { return '/login'; } if (isLoggedIn && isGoingToLogin) { return '/'; } return null; }, routes: [ GoRoute( path: '/login', builder: (context, state) => LoginScreen(), ), GoRoute( path: '/', builder: (context, state) => HomeScreen(), ), ],);5. 実務でのルーティングパターン
Section titled “5. 実務でのルーティングパターン”パターン1: タブナビゲーション
Section titled “パターン1: タブナビゲーション”final router = GoRouter( routes: [ ShellRoute( builder: (context, state, child) => MainScreen(child: child), routes: [ GoRoute( path: '/home', builder: (context, state) => HomeTab(), ), GoRoute( path: '/search', builder: (context, state) => SearchTab(), ), GoRoute( path: '/profile', builder: (context, state) => ProfileTab(), ), ], ), ],);パターン2: モーダル表示
Section titled “パターン2: モーダル表示”// モーダルとして表示showModalBottomSheet( context: context, builder: (context) => ModalScreen(),);
// 全画面モーダルNavigator.push( context, MaterialPageRoute( builder: (context) => FullScreenModal(), fullscreenDialog: true, ),);パターン3: カスタムページ遷移
Section titled “パターン3: カスタムページ遷移”class CustomPageRoute extends PageRouteBuilder { final Widget child;
CustomPageRoute({required this.child}) : super( transitionDuration: Duration(milliseconds: 300), pageBuilder: (context, animation, secondaryAnimation) => child, );
@override Widget buildTransitions( context, animation, secondaryAnimation, child, ) { return SlideTransition( position: Tween<Offset>( begin: Offset(1.0, 0.0), end: Offset.zero, ).animate(animation), child: child, ); }}
// 使用例Navigator.push( context, CustomPageRoute(child: SecondScreen()),);6. よくある問題と解決策
Section titled “6. よくある問題と解決策”問題1: 戻るボタンが動作しない
Section titled “問題1: 戻るボタンが動作しない”解決策: WillPopScopeまたはPopScopeを使用します。
PopScope( canPop: false, onPopInvoked: (didPop) { if (!didPop) { // カスタム処理 Navigator.pop(context); } }, child: Scaffold(...),)問題2: ルートが見つからない
Section titled “問題2: ルートが見つからない”解決策: ルート定義を確認し、パスが正しいか確認します。
// デバッグモードでルート情報を表示if (kDebugMode) { print('Current route: ${GoRouter.of(context).routerDelegate.currentConfiguration}');}これで、Flutterでのルーティングとナビゲーションの実装方法を理解できるようになりました。