I want to navigate to different Routes using a Drawer, though I do not want to open a new instance of a Route each time I tap on it if I am already on that Route, rather I would
You could just use one:
Get.currentRoute
with this package: https://pub.dev/packages/get
And you would have the current route.
However you wouldn't need this, because unlike the standard Flutter, Get prevents the user from accidentally clicking a button twice (if the user is on a low-cost device it will happen after a jank).
Then you would only need to use: Get.to(Home());
and ready, it would be done!
Currently, Getx is practically indispensable for projects with Flutter for this reason. I looked at all the questions, and they are cool, but they usually involve using a popUntil to gain access to the route and this can seem like a hack when another developer reads your code. With GetX you will not have this double click problem, because it only navigates to another page of the same if you expressly disable it using Get.to(Page(), preventDuplicates: false); Remembering that this is the exception, in your case you could simply use: Get.to(Page()); and navigate to the next page without any risk of duplicate routes, because preventing that sort of thing already comes standard on it.
Getting the current route also seems to be something that involves a lot of boilerplate, with Get you get the name of the current route (even if you don't have named routes it will give you the name of it anyway), using a simple: Get.currenteRoute
.
Well, it's a little late to answer that, but I hope you and other users who read this enjoy
This is my solution. Based on the Rémi Rousselet solution. The only difference is that prevent te pop of the "last" route remaining.
bool routeFound = false;
String routeName = "/myRoute";
//remove all the routes and stops if find the routeName or if is the last one
Navigator.popUntil(context, (route) {
if (route.settings.name == routeName) {
expenseRouteFound = true;
}
//print("route " + routeName + " founded in stack: " + routeFound.toString());
//print("last remaining route into the stack: " + route.isFirst.toString());
return routeFound || route.isFirst;
});
//print("route " + routeName + " founded in stack: " + routeFound.toString());
if (!routeFound) {
//print("time to push the route: " + routeName + "!");
Navigator.of(context).pushNamedAndRemoveUntil(routeName, (_)=>false);
}
for me i'm using the laziest easiest way since no answer here helped me in main route, i just use drawer class and pass the name of the current route to the drawer constructor like this :
class MyDrawer extends StatelessWidget {
final String currentRoute;
MyDrawer(this.currentRoute);
@override
Widget build(BuildContext context) {
return Drawer(
child: ListView(
children: <Widget>[
InkWell(
child: Text('secondRoute'),
onTap: () {
if (currentRoute != 'secondRoute')
Navigator.push(context,
MaterialPageRoute(builder: (context) => secondRoute()));
}),
InkWell(
child: Text('thirdRoute'),
onTap: () {
if (currentRoute != 'thirdRoute')
Navigator.push(context,
MaterialPageRoute(builder: (context) => thirdRoute()));
}),
and in the routes where i call MyDrawer class i pass the name of the current route
drawer: MyDrawer('secondRoute'),
Navigator
doesn't expose the current route.
What you can do instead is use Navigator.popUntil(callback)
as popUtil
pass to the callback the current Route
, which includes it's name and stuff.
final newRouteName = "/NewRoute";
bool isNewRouteSameAsCurrent = false;
Navigator.popUntil(context, (route) {
if (route.settings.name == newRouteName) {
isNewRouteSameAsCurrent = true;
}
return true;
});
if (!isNewRouteSameAsCurrent) {
Navigator.pushNamed(context, newRouteName);
}
This is my solution.
void redirect(screen){
Navigator.popUntil(context, (route) {
if ( route.settings.name != screen) {
Navigator.pushNamed(context, screen);
}
return true;
});
}
Use following code to check if route is top most ...
Route route = MaterialPageRoute(builder: (context) => WidgetName());
if(route.isCurrent){
}