go_router: 導入 使い方 - Ki-Kobayashi/flutter_wiki GitHub Wiki
fvm flutter pub add go_router
dependencies:
flutter:
sdk: flutter
・・・
go_router: ^10.2.0
.
💎新規作成クラス一覧(config/router/ココ)
- app_router.dart
- route_path.dart
💎編集クラス一覧
- application.dart
.
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:weather_riverpod_prac/config/router/route_path.dart';
final routerProvider = Provider((ref) {
final rootNavigatorKey = GlobalKey<NavigatorState>(debugLabel: 'root');
final tabHomeNavigatorKey = GlobalKey<NavigatorState>(debugLabel: 'tabHome');
final tabSearchNavigatorKey =
GlobalKey<NavigatorState>(debugLabel: 'tabSearch');
final tabMainNavigatorKey =
GlobalKey<NavigatorState>(debugLabel: 'tabMain');
final tabNoticeNavigatorKey =
GlobalKey<NavigatorState>(debugLabel: 'tabNotice');
final tabAccountNavigatorKey =
GlobalKey<NavigatorState>(debugLabel: 'tabAccount');
final isLoggedIn = ref.watch(authControllerProvider
.select((state) => state.valueOrNull?.isLoggedIn)) ??
false;
return GoRouter(
navigatorKey: rootNavigatorKey,
debugLogDiagnostics: kDebugMode,
// アプリが起動した時
initialLocation: isLoggedIn ? IndexPage.path : StartPage.path,
observers: [
ref.watch(routeObserverProvider),
],
routes: <RouteBase>[
GoRoute(
path: StartPage.path,
name: StartPage.pathName,
builder: (BuildContext context, GoRouterState state) {
return const StartPage();
},
),
GoRoute(
parentNavigatorKey: rootNavigatorKey,
path: SignUpPage.path,
name: SignUpPage.pathName,
builder: (BuildContext context, GoRouterState state) {
return SignUpPage();
},
),
GoRoute(
parentNavigatorKey: rootNavigatorKey,
path: LoggedInPage.path,
name: LoggedInPage.pathName,
builder: (BuildContext context, GoRouterState state) {
return LoggedInPage();
},
),
// 💡ボトムナビの状態保持してくれるやつ
StatefulShellRoute.indexedStack(
parentNavigatorKey: rootNavigatorKey,
builder: (context, state, navigationShell) {
return IndexPage(
navigationShell: navigationShell,
);
},
branches: [
StatefulShellBranch(
navigatorKey: tabHomeNavigatorKey,
routes: <RouteBase>[
GoRoute(
path: HomePage.path,
name: HomePage.pathName,
builder: (context, state) {
return HomePage();
},
),
],
),
StatefulShellBranch(
navigatorKey: tabSearchNavigatorKey,
routes: <RouteBase>[
GoRoute(
path: SearchPage.path,
name: SearchPage.pathName,
builder: (context, state) => const SearchPage()
),
],
),
StatefulShellBranch(
navigatorKey: tabMainNavigatorKey,
routes: <RouteBase>[
GoRoute(
path: MainPage.path,
name: MainPage.pathName,
builder: (context, state) => isLoggedIn
? const MainPage()
: LoginPage(),
),
],
),
StatefulShellBranch(
navigatorKey: tabNoticeNavigatorKey,
routes: <RouteBase>[
GoRoute(
path: NoticePage.path,
name: NoticePage.pathName,
// お知らせタブ:既読・未読処理があるためログイン確認が必要
builder: (context, state) => const NoticePage(),
routes: <RouteBase>[
GoRoute(
path: NoticeDetailPage.path,
name: NoticeDetailPage.pathName,
builder: (context, state) {
// 💡値の受け取り
final noticeInfo = state.extra as NoticeInfo;
return NoticeDetailPage(notice: noticeInfo);
},
),
],
),
],
),
StatefulShellBranch(
navigatorKey: tabAccountNavigatorKey,
routes: <RouteBase>[
GoRoute(
path: AccountSettingPage.path,
name: AccountSettingPage.pathName,
builder: (context, state) => const AccountSettingPage(),
routes: <RouteBase>[
GoRoute(
path: APage.path,
name: APage.pathName,
builder: (context, state) {
return const APage();
},
),
GoRoute(
path: BPage.path,
name: BPage.pathName,
builder: (context, state) {
return BPage();
},
),
],
),
],
),
],
),
GoRoute(
parentNavigatorKey: rootNavigatorKey,
path: ItemDetailPage.path,
name: ItemDetailPage.pathName,
builder: (context, state) {
final itemId = state.extra ?? '' as String;
return ItemDetailPage(itemId: itemId);
},
),
],
);
});
.
class RoutePath {
static const String top = '/';
static const String itemList = '/items';
static const String itemDetail = '/items/detail';
・・・
}
.
class Application extends ConsumerWidget {
const Application({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final goRouter = ref.watch(routerProvider); 👈追加
return MaterialApp.router(
debugShowCheckedModeBanner: false, // デバッグラベルの非表示
routerConfig: goRouter, 👈追加
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
// home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
.
AppRouter.dartと併せて、以下を設定する
class IndexPageextends StatelessWidget {
const IndexPage({
super.key,
required this.navigationShell,
});
static const path = '/';
static const pathName = 'index';
final StatefulNavigationShell navigationShell;
@override
Widget build(BuildContext context) {
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () => primaryFocus?.unfocus(),
onLongPress: () => primaryFocus?.unfocus(),
child: Scaffold(
appBar: navigationShell.currentIndex == 0
? const SearchAppbar()
: null,
body: WillPopScope(
onWillPop: () async {
return false;
},
child: SafeArea(
child: navigationShell,
),
),
bottomNavigationBar: BottomNavigationBar(
currentIndex: navigationShell.currentIndex,
onTap: (index) => _goBranch(index),
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
activeIcon: _tabIcon('assets/images/tab_active_xxx.png'),
icon: _tabIcon('assets/images/tab_xxx.png'),
label: 'AAA',
),
BottomNavigationBarItem(
activeIcon: _tabIcon('assets/images/tab_active_xxx.png'),
icon: _tabIcon('assets/images/tab_xxx.png'),
label: 'AAA',
),
BottomNavigationBarItem(
activeIcon: _tabIcon('assets/images/tab_active_xxx.png'),
icon: _tabIcon('assets/images/tab_xxx.png'),
label: 'AAA',
),
BottomNavigationBarItem(
activeIcon: _tabIcon('assets/images/tab_active_xxx.png'),
icon: _tabIcon('assets/images/tab_xxx.png'),
label: 'AAA',
),
BottomNavigationBarItem(
activeIcon: _tabIcon('assets/images/tab_active_xxx.png'),
icon: _tabIcon('assets/images/tab_xxx.png'),
label: '',
),
],
type: BottomNavigationBarType.fixed,
),
),
);
}
SizedBox _tabIcon(String path) {
return SizedBox(
height: 40.0,
width: 50.0,
child: Image.asset(path),
);
}
void _goBranch(int index) {
navigationShell.goBranch(
index,
initialLocation: index == navigationShell.currentIndex,
);
}
}
.
.
.
.
.
.