Skip to content

ルーティングとナビゲーション

Flutterルーティングとナビゲーション完全ガイド

Section titled “Flutterルーティングとナビゲーション完全ガイド”

Flutterでの画面遷移とルーティングの実装方法を、基本的な方法から高度なパターンまで詳しく解説します。

// 画面遷移
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SecondScreen(),
),
);
// 前の画面に戻る
Navigator.pop(context);
// 戻り値を返す
Navigator.pop(context, '戻り値');
// 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を使用したルーティング”
dependencies:
go_router: ^12.0.0
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.dart
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp.router(
routerConfig: router,
);
}
}
// 画面遷移
context.go('/second');
// 戻る
context.pop();
// 戻り値を返す
context.pop('戻り値');
GoRoute(
path: '/search',
builder: (context, state) {
final query = state.uri.queryParameters['q'] ?? '';
return SearchScreen(query: query);
},
);
// 使用例
context.go('/search?q=flutter');
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(),
),
],
),
],
),
],
);
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(),
),
],
),
],
);
// モーダルとして表示
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()),
);

問題1: 戻るボタンが動作しない

Section titled “問題1: 戻るボタンが動作しない”

解決策: WillPopScopeまたはPopScopeを使用します。

PopScope(
canPop: false,
onPopInvoked: (didPop) {
if (!didPop) {
// カスタム処理
Navigator.pop(context);
}
},
child: Scaffold(...),
)

解決策: ルート定義を確認し、パスが正しいか確認します。

// デバッグモードでルート情報を表示
if (kDebugMode) {
print('Current route: ${GoRouter.of(context).routerDelegate.currentConfiguration}');
}

これで、Flutterでのルーティングとナビゲーションの実装方法を理解できるようになりました。