INDEX / JOURNAL / LOG-011
VOL. 2026 · ENGINEERING
SERIES 4 / 8
LOG-011 · NAVIGATION

画面はスタックで積まれる

PUBLISHED
2026 · 08 · 21
AUTHOR
MIGIWAYA
READ
約 6 分
TAGS
#flutter#dart

§ 01STACK

DART
Navigator.push(
context,
MaterialPageRoute(builder: (context) => ItemDetailScreen(item: item)),
);

§ 02LIMIT

§ 03GOROUTER

lib/router/app_router.dartDART
final router = GoRouter(
initialLocation: '/',
routes: [
GoRoute(path: '/', builder: (context, state) => const HomeScreen()),
GoRoute(
path: '/items/:id',
builder: (context, state) => ItemDetailScreen(
id: state.pathParameters['id']!,
),
),
GoRoute(path: '/sign-in', builder: (context, state) => const SignInScreen()),
],
);
lib/app.dartDART
MaterialApp.router(routerConfig: router)

§ 04REDIRECT

lib/router/app_router.dartDART
GoRouter(
redirect: (context, state) {
final signedIn = authService.isSignedIn;
final goingToSignIn = state.matchedLocation == '/sign-in';
 
if (!signedIn && !goingToSignIn) return '/sign-in'; // 未ログインは追い返す
if (signedIn && goingToSignIn) return '/'; // ログイン済みなら戻す
return null; // そのまま通す
},
routes: [...],
);

§ 05SHELL

lib/router/app_router.dartDART
StatefulShellRoute.indexedStack(
builder: (context, state, navigationShell) =>
MainScaffold(navigationShell: navigationShell),
branches: [
StatefulShellBranch(routes: [
GoRoute(path: '/stock', builder: (context, state) => const StockScreen()),
]),
StatefulShellBranch(routes: [
GoRoute(path: '/recipes', builder: (context, state) => const RecipeScreen()),
]),
],
)
lib/widgets/main_scaffold.dartDART
BottomNavigationBar(
currentIndex: navigationShell.currentIndex,
onTap: (index) => navigationShell.goBranch(
index,
// 同じタブをもう一度押したら、そのタブの先頭へ戻る
initialLocation: index == navigationShell.currentIndex,
),
)

§ 06LIFETIME

DART
// やってはいけない
Widget build(BuildContext context) {
final router = GoRouter(routes: [...]); // 再構築のたびに新しいルーター
return MaterialApp.router(routerConfig: router);
}
lib/router/app_router.dartDART
final routerProvider = Provider<GoRouter>((ref) {
return GoRouter(routes: [...]);
});
lib/coordinators/notification_tap_coordinator.dartDART
void onNotificationTap(String payloadPath) {
router.go(payloadPath); // 例: '/items/42'
}

§ 08SUMMARY

脚注 · NOTES
  1. [1]
  2. [2]
  3. [3]
  4. [4]
  5. [5]
同シリーズ · Flutter の基礎を実コードで学ぶ II
§ + RELATED すべて見る →
INQUIRY
CONTACT
LOCATION
STATUS
Active / Open
ESTABLISHED
2024 · 5 · 5
FORM