Getting back to the first page in the stack in Flutter - flutter

In my Flutter app I want to get back to the home page by removing everything but the first page from the stack.
I've found two ways of doing it and they both seem to work but since I'm fairly new to Flutter I was wondering of one of these methods is best :-
Navigator.of(context).popUntil((route) => route.isFirst);
Navigator.pushNamedAndRemoveUntil(context, '/', (_) => false);

You can use both of them.
But, in my own opinion (as I read the docs), in order to use the pushNamedAndRemoveUntil method, you need to name your routes.
On the other hand, If you do not use named routes, you can use the popUntil method. Because it's not using named routes and much simpler.

The answer is pushAndRemoveUntil. There is a method like this available for you, if you don't want to use named route in your flutter app. Read about it here.
So, now what you can do it:
// It accepts Route object, so we can use Material Page Route
// We name your first page as HomePage, so don't get Confused
Navigator.pushAndRemoveUntil(context,
MaterialPageRoute(builder: (context) => HomePage()),
(_) => false
);
Read about MaterialPageRoute class, and add it to your bucket, because it is a very useful thing, if you don't know about it already.

Related

How to properly navigate to previous page with getx?

I have a pages
A>B>C>D>E
I want to navigate back from page E>B>A
I tried with
Get.offNamedUntil('B', (route) => false);
But it worked like E>B and then doesn't redirect back to A. Is there any other way to do so?
I would say that you forget a / in the named route, and as a recommendation, don't return false in the callback, set a condition to stop if the named route was not found in the routes stack, as example use route.isFirst :
Get.offNamedUntil('/B', (Route<dynamic> route) => route.isFirst);

Keep Navigator state data (provider/InheritedWidget) when pushing routes

In my flutter app I have a list of instances, when user clicks one I open the instance page and provide the InstanceData model to it using
Navigator.push(context, MaterialPageRoute(builder: (context) =>
ChangeNotifierProvider(
create: (_) => InstanceData(...),
child: Instance()
)
));
This does work, but when the Instance widget does Navigator.push, the provider data is lost because my provider is below the app's Navigator.
I googled for a solution and found that I can do:
Navigator.push(context, MaterialPageRoute(builder: (context) =>
ChangeNotifierProvider(
create: (_) => InstanceData(),
child: Navigator(
onGenerateRoute: (settings) {
return MaterialPageRoute(
builder: (context) => Instance()
);
},
)
)
));
Here's the dartpad to show it: https://dartpad.dev/?id=51fcbabb1ad401afb193558ccde3b5e1
Now, all (even deeply nested) widgets that are opened from Instance() will have access to the InstanceData. Also, I actually need multiple nesting. E.g. we click Instance and create Provider for it, then inside Instance we click Area and I want all widgets from Area() and below to have access to both InstanceData and AreaData, so I will need to create another Navigator to hold AreaData. Think of it as in this example:
https://medium.com/coding-with-flutter/flutter-case-study-multiple-navigators-with-bottomnavigationbar-90eb6caa6dbf
which shows that we keep separate history inside each Tab. Now, if each my Instance is in its own Tab, and Instance also has tabs panel with each tab being Area that also has to keep its own history - that's what I need.
However I am new to flutter and I am not sure if that's the correct approach. Creating own Navigator on each route push just so that my Inherited/Provider data is accessible? Looks like a hack to me.
E.g. what if I want to show two Instance() widgets side by side - I would wrap them with their own Navigator just to pass the data but isn't navigator supposed to track pages/screens instead? How will it behave with the Back button?
So can somehow confirm the solution and if not, them suggest a state management for flutter that will allow to create do something like
Navigator.push(context, MaterialPageRoute(builder: (context) =>
CoolProvider(
create: (_) => InstanceData(...),
child: Instance()
)
));
where CoolProvider does work for any Navigator.push() inside any child widget of the Instance(), even if that's some "CoolNavigator.push" instead. Maybe it's some kind of sub-routes? E.g. Navigator.pushSubRoute() so that the main route is still there?
Maybe it's not even about Navigator? E.g. in the side-by-side Instances having Navigator is almost meaningless - user can't navigate to both instances at once, but I do need each Instance() to be clickable and to go to nested Areas with the InstanceData() available to those widgets.
Update: In fact I tried it side by side here:
https://dartpad.dev/?id=3c299f3972ac18a1b70b841380eaffef
and it seems to be working fine, because without the Navigator the push just replaces the whole page, while with navigator it correctly replaces just the half-side widget.
So is it the way I suppose to do? Any drawbacks - need to use navigatorKey, etc?
P.S. There are of course alternatives like passing InstanceData to each child ctor but that's a lot of manual properties passing around... having the Provider is surely a better way.

callback function for navigation in Flutter

In Navigator, we can use .then.
for eg:
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => XyzScreen(),
),
).then((value) => _someFuncion());
so is there any way to implement the same in go_router?
see https://github.com/flutter/flutter/issues/99663 and
It seems like as a main go_router functionality it is not supported yet. Mainly since it is incompatible with browsers otherwise. Support for fixing this is there, however in the project it has a somewhat low priority.
https://stackoverflow.com/a/73962826/4986655
here you can find a workaround, by registering a listener when the route changes.
So you could => ignore while on the other page (or even subroutes of that page), call the callback when back on this page + unregister the listener, and unregister the listener if otherwise or sth similar.

Why Pages can match the Navigator.push on flutter?

when I use navigator2.0 pages to control route.
then when I use Navigator.push( context, MaterialPageRoute(builder: (_) => DemoPage()));
that's works ok.
but I did not change the pages, I also find pages don't changed.
Why Pages can match the Navigator.push?
for example: pages only have one,then Navigator.push(),there are actually two routes ,but page.length has always been 1.
running effect is ok, pop can also work ok,everything looks ok, how is this done?
Thank you very much for your reply。

how to navigate to new screen without setting routes in flutter

I'm building a shopping app and I can create a category from the database! however, I'm having a problem on how to navigate to that new category without defining routes in main.dart
Do you try this?
Navigator.push(
context,
MaterialPageRoute(builder: (context) => NewScreen()),
);
Or, alternatively, you can use onGenerateRoute to define how your routing should work, and do whatever black magic you desire in this function. :-)