I have a Flutter web app with a custom side navigation bar which is displayed on every page. So that I can always show the same side navigation bar while still keeping URL navigation I am using the go_router
package with all of the pages in a ShellRoute
.
Now I want to slide transition up to a navigation item below the current one and visa-verse. How can I achieve this?
Here’s an over simplified version of my code
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp.router(
routerConfig: GoRouter(
initialLocation: "/dash",
routes: [
ShellRoute(
builder: (context, state, child) => SideNavBarPage(subPage: child),
routes: [
GoRoute(
path: '/dash',
builder: (context, state) => DashPage(),
),
GoRoute(
path: '/other',
builder: (context, state) => OtherPage(),
),
GoRoute(
path: '/another',
builder: (context, state) => AnotherPage(),
),
],
),
],
),
);
}
}
class SideNavBarPage extends StatelessWidget {
final Widget subPage;
const SideNavBarPage({
required this.subPage,
super.key,
});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Row(
children: [
CustomSideNavBar(
items: [
CustomSideNavBarItem(onTap: () => context.go("/dash")),
CustomSideNavBarItem(onTap: () => context.go("/other")),
CustomSideNavBarItem(onTap: () => context.go("/another")),
],
),
Expanded(child: subPage),
],
),
);
}
}
For example: if I wanted to switch from /another
to /dash
I would want to transition down from top to bottom, whereas from /dash
to /other
I would want to slide up from bottom to top.
2
Answers
UPDATE (RECOMMENDED):
I have now developed a package to tackle this very problem. Using this go_router_tabs package the solution is much simpler with only a few extra lines of code:
This solution removes the need for global controllers. The package can also handle nested navigation bar setups and will always know which navigation item is selected no matter how deeply nested the current route is and how the user got there.
ORIGINAL ANSWER (NO LONGER RECOMMENDED):
First let's create a controller that updates the selected tab in the navigation rail. It will therefore be able calculate the direction of the slide transition:
By adding the
redirect
method of the controller to theGoRouter
we can cause the navigation bar to update every time we navigate to a new page:This is an example page with the navigation rail:
This is an example page displayed next to the navigation rail.
Now let's create a
GoRouter
CustomTransitionPage
that let's us control the direction of the slide transition:Now we can add our routes to the
GoRouter
inMyApp
:Use auto_route: ^7.1.0 for navigation in flutter, it have transitionBuilder so that you can simply enable transition animation between pages.
Eg: