Reputation: 91
I am currently developing a flutter application using the go_router package.
At the base there is one Shellroute with 4 routes in total. So this is the main screen containing a "Home", "Search", "Events" and an "Account" page.
Then I have multiple "secondary" screens that I want as sub routes of all of the above mentioned. So the shell route (one of those routes) needs to be the first in the hierarchy.
Currently I have a setup like this:
created an entity class
abstract class ScreenEntity {
ScreenEntity(this.name, this.path);
final String name;
final String path;
}
All my Screens inherit this.
I then have a whole list of those screens so I don't need to write the whole go router stack myself.
const mainScreens = <ScreenEntity>[
ScreenHome(),
ScreenSearchActivity(),
ScreenParty(),
ScreenAccount(),
];
final secondaryScreens = <ScreenEntity>[
const ScreenLoggingErrors(),
ScreenUserSettings(),
const ScreenFriendList(),
const ScreenNotification(),
const ScreenSearchUser(),
const ScreenCreateLocation(),
const ScreenSettings(),
const ScreenPartySettings(),
const ScreenSettingsPayments(),
const ScreenCamera(),
const ScreenPartyArchive(),
const ScreenPartyCreateFlow(),
const ScreenIntroduction(),
ScreenPolicyAgreement(),
const ScreenLocations(),
];
And some other smaller lists. Then I've just iterated through them as sub routes in the first of the 4 main screens.
GoRouter createGoRouter(Ref ref) => GoRouter(
initialLocation: mainScreens.first.path,
refreshListenable: ref.read(deeplinkStateProvider),
navigatorKey: _rootNavigatorKey,
routes: [
ShellRoute(
navigatorKey: _shellNavigatorKey,
pageBuilder: (context, state, child) => MaterialPage(
child: MainScreenWrapper(child: child),
),
routes: [
GoRoute(
parentNavigatorKey: _shellNavigatorKey,
path: mainScreens[0].path,
name: mainScreens[0].name,
pageBuilder: (context, state) {
return NoTransitionPage(child: mainScreens[0] as Widget);
},
routes: [
...secondaryScreens.map(
(screen) => GoRoute(
parentNavigatorKey: _rootNavigatorKey,
path: screen.path,
name: screen.name,
pageBuilder: (context, state) => MaterialPage(
child: screen as Widget,
),
),
),
...screensWithPathParams.map(
(screenEntity) => GoRoute(
parentNavigatorKey: _rootNavigatorKey,
path: screenEntity.path,
name: screenEntity.name,
pageBuilder: (context, state) {
final param =
state.pathParameters[screenEntity.paramName];
return MaterialPage(
child: screenEntity.build(context, param!),
);
},
),
),
...screensWithParams.map(
(screenEntity) => GoRoute(
parentNavigatorKey: _rootNavigatorKey,
path: screenEntity.path,
name: screenEntity.name,
pageBuilder: (context, state) {
final extra = state.extra as ScreenProps;
return MaterialPage(
child: screenEntity.build(context, extra),
);
},
),
),
...modalEntities.map(
(modalEntity) => GoRoute(
parentNavigatorKey: _rootNavigatorKey,
path: modalEntity.path,
name: modalEntity.name,
pageBuilder: (context, state) => ModalPage(
isDismissible: modalEntity.isDismissible,
isScrollControlled: modalEntity.isScrollControlled,
enableDrag: modalEntity.enableDrag,
builder: (context) => modalEntity.build(
context,
state.extra as ModalProps,
ref: ref,
),
),
),
),
...modalEntitiesWithPath.map(
(modalEntity) => GoRoute(
parentNavigatorKey: _rootNavigatorKey,
path: modalEntity.path,
name: modalEntity.name,
pageBuilder: (context, state) {
final param = state.pathParameters[modalEntity.pathParam];
return ModalPage(
isDismissible: modalEntity.isDismissible,
isScrollControlled: modalEntity.isScrollControlled,
enableDrag: modalEntity.enableDrag,
builder: (context) => modalEntity.build(
context,
state.extra as ModalProps?,
param ?? '',
ref: ref,
),
);
},
),
),
...dialogEntities.map(
(dialogEntity) => GoRoute(
parentNavigatorKey: _rootNavigatorKey,
path: dialogEntity.path,
name: dialogEntity.name,
pageBuilder: (context, state) => DialogPage(
barrierDismissible: dialogEntity.barrierDismissible,
builder: (context) => dialogEntity.build(
context,
state.extra as DialogProps,
ref: ref,
),
),
),
),
],
),
GoRoute(
parentNavigatorKey: _shellNavigatorKey,
path: mainScreens[1].path,
name: mainScreens[1].name,
pageBuilder: (context, state) {
return NoTransitionPage(child: mainScreens[1] as Widget);
},
),
GoRoute(
parentNavigatorKey: _shellNavigatorKey,
path: mainScreens[2].path,
name: mainScreens[2].name,
pageBuilder: (context, state) {
return NoTransitionPage(child: mainScreens[2] as Widget);
},
),
GoRoute(
parentNavigatorKey: _shellNavigatorKey,
path: mainScreens[3].path,
name: mainScreens[3].name,
pageBuilder: (context, state) {
return NoTransitionPage(child: mainScreens[3] as Widget);
},
),
],
),
...primaryScreens.map(
(screen) => GoRoute(
path: screen.path,
name: screen.name,
pageBuilder: (context, state) => MaterialPage(
child: screen as Widget,
),
),
),
],
redirect: (context, state) async {
...
},
);
What I wanted: I want that all these "secondary" screens need one of these four screens under them. That when I use context.go() it automatically uses one of the main screens that I am currently on and puts the routed screen on top.
But the way I implemented it right now it routes to the first page of the shell route every time.
Upvotes: 0
Views: 73