Have you ever come across a situation where you needed to show the pre-created stack of screens on the app when the user taps on notifications or the user taps on deep links. Ever wondered how that can be done in Flutter?
Check out this behavior,
Here, if you see when the app is launched there are already two screens on top of the root screen.
If we observe the behavior closely, we know that it’s all about navigation. When it comes to navigation every Flutter developer has heard about the Navigator widget. It manages the screen navigation in Flutter.
We normally call Navigator’s push()/pushNamed() methods to show the new screen and pop() to remove.
What we usually ignore is the Navigator itself is a StatefulWidget in Flutter. That means you can wrap it with any widget you want and create your stack of screens.
But what if you want to show a stack of screens when the app is launched?
Well, I’ve checked the Navigator widget’s source code and found one widget parameter which will allow us to achieve this behavior.
onGenerateInitialRoutes
If you check out comments above its declaration it says,
The callback must return a list of [Route] objects with which the history will be primed.
Meaning, we can generate our own initial list of Routes (e.g. screens) and show it pre-ready when the user opens the screen with the Navigator widget at the root of the screen.
Navigator widget at the root of the screen
If you check the MaterialApp widget source code you will see that it uses WidgetApp and somewhere in the source code of WidgetApp has Navigator widget as its root widget.
If you see the WidgetApp’s source code, you will see it passes onGenerateInitialRoutes to the Navigator widget. Now, this parameter can be initialized in MaterialApp.
So what I’ve done is to use this parameter to pass initial widgets when the app is launched and voila! You will see those screens already stacked up.
void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Navigators', onGenerateInitialRoutes: defaultGenerateInitialRoutes, debugShowCheckedModeBanner: false, onGenerateRoute: generateRoute, theme: ThemeData( primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, ), ); } }
Here is the defaultGenerateInitialRoutes() method,
List defaultGenerateInitialRoutes(String initialRouteName) { List routes = new List(); routes.add(MaterialPageRoute(builder: (context) => RootWidget())); routes.add(MaterialPageRoute(builder: (context) => SecondWidget())); routes.add(MaterialPageRoute(builder: (context) => ThirdWidget())); return routes; }
In this method, I’ve created a list of the MaterialPageRoute widget and returned it. I’ve created three widgets: RootWidget, SecondWidget, and ThirdWidget.
Navigator widget will be initialized with these routes only and show these screens when renders
GitHub repo: harshsoni1110/custom_navigation
You can use this approach to solve a couple of problems such as,
Hope you find this information about Navigator insightful. Cheers!
References
Thanks for reading this article. Leave a comment below if you have any doubts or feedback about this article. You can clap if you find this article helpful.