Navigating in and outside CupertinoTabBar View - flutter

this is my first app in Flutter, everything was fine and smooth util now that I´m geeting a little bit blocked.
I cannot navigate between a CupertinoTabBar and my Login display (that shouldn´t have one) the way I show you on the image.
Login works fine and when receives a 200 response from server, navigates to the view with the CupertinoTabBar.
But when I press on the LogOut button, I´d need to comeback to the loginView, without any tabBar.
The only way I´ve been able to navigate back to login is like that:
Navigator.push(context, CupertinoPageRoute(builder: (context) => LoginView()),);
And that keeps my LoginView inside the tabBar in the widgets stack, and what is worse, if I logIn again I endup stacking another tabBar over the previous one.
What could be a better approach for that?
Many Thanks,
Gabi

You can use pushAndRemoveUntil to pop routes that you don't need in stack. Probably, you want to remove all the routes like that:
Navigator.of(context).pushAndRemoveUntil(CupertinoPageRoute(builder: (context) => LoginView()), (r) => false);
or, if your current route is logout, you can replace it with login route and route stack will remain the same:
Navigator.of(context).pushReplacement(CupertinoPageRoute(builder: (context) => LoginView()));

Related

How to prevent going back to previous page on Flutter Web via browser back button?

After a user successfully logged in in my Flutter web app, it should be taken to a dashboard view.
The user then should not be able to navigate back to the login screen by pressing the browser back button.
I tried a lot of things, replacing the route, popping the route and then pushing the next route, all did not work.
Also using WillPopScope in the dashboard page does not work. Pressing the browser back button does not fire onWillPop.
Found some similar questions, but they all end up suggesting WillPopScope or replacing the route, both did not work for me.
Any idea what I could do?
Seems like you can't intercept the browser back buttons.
I solved the problem by using a RouteGuard of the auto_route package which intercepts the navigation and checks if the user is authenticated or not. If the user is already authenticated, the navigation to the Signin page is canceled.
Check the auto_route package for examples and further explanation: https://pub.dev/packages/auto_route#route-guards
Wrap it inside a WillPopScope and return false
WillPopScope(
onWillPop: () async => Future.value(false),
child: DashboardView(),
),

Flutter: How to pop last visited screen from stack in flutter

Let say i have three screens: wallet, payments, add card. I want to pop payments screen from stack when i'm on add card screen and navigate it to wallet screen without using navigator.push on click on icon plus the back icon of device.
here is the flow of screen:
wallet screen has a button which navigate to the payments screen, then payments screen has a button which navigate to the add card screen . So, now i want when i am on add card screen and click on back icon of android or the icon which is on add card screen both should navigate to wallet screen.
Please help how to do this.
It's not very clear from your question how your navigation stack should look: Is payments first in the stack, and can you go from there to add card and wallet? Or should only one exist?
I think you can use pushReplacement: https://api.flutter.dev/flutter/widgets/Navigator/pushReplacement.html
That way, it'll automatically replace the current route with the new one, and your back button will simply close the app (or go back to the screen before it). If you want some custom behavior when the back button is pressed, you can always use a WillPopScope: https://api.flutter.dev/flutter/widgets/WillPopScope-class.html
Navigator.removeRoute(context, MaterialPageRoute(builder: (context) => payments()));
use this code when you remove your payments screen
Please try this below code
PopAndPushNamed ->
Pop the current route off the navigator that most tightly encloses the given context and push a named route in its place.
It pops payments screen from the navigation stack and only wallet screen remains in Navigation stack
Navigator.popAndPushNamed(context, '/addCard');
PushNamedAndRemoveUntil ->
It pushes the route with the given name (Wallets) onto the navigator, and then remove all the previous routes until the predicate returns true. Here it is using a RoutePredicate that always returns false (Route route) => false. In this situation it removes all of the routes except for the wallets route pushed.
//named
Navigator.of(context)
.pushNamedAndRemoveUntil('\wallets', (Route<dynamic> route) => false);
//not named
Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (context) =>
Wallets()), (Route<dynamic> route) => false),
PopUntil ->
Calls pop repeatedly on the navigator that most tightly encloses the given context until the predicate returns true.
The predicate may be applied to the same route more than once if Route.willHandlePopInternally is true.
To pop until a route with a certain name, use the RoutePredicate returned from ModalRoute.withName.
Navigator.popUntil(context, ModalRoute.withName('/wallets'));
try this:
Navigator.pushReplacement()

API data from provider seems to get lost during Navigation

I am a beginner level Flutter developer trying to resolve the issue with the Navigation stack.
In the existing app:
When user logs in to the app, login api call is shooted
Homescreen is rendered with Navigator.popUntill method
All the APIs in the providers get shooted and the respective tabs/screens get filled with api data.
Now, I want to include Onboarding screens before Homescreen, so I made below changes:
Navigator.push method used to include Onboarding screens.
After onboarding screens are over, user clicks on "To app" button
On click of "To app" button, the login call is made again
User is redirected to Homescreen with Navigator.popUntill method.
But now the data from providers is lost as the respective screens do not show any data. I am pretty sure that something is going wrong with the Navigation stack when I use Navigator.push method to add Onboarding screens but I do not have much expertise in Flutter to debug the issue. Need help with restoring the provider data when navigating to Onboarding screens.
I think that the cause isn't in a navigation stack. Probably you placed Provider widget lower than navigation (MaterialApp).
Try something like that or show your code for better understanding.
Provider(
create: (context) => ClassThatCallsAPI(),
child: MaterialApp(
// Navigator placed here and any route will
// get the same data from provider
// and also can put some

Flutter navigation pop from which screen

Is there anyway to check route name of last screen after pop? When application start and land on home screen, there are several widgets like view profile, product carousel and so on.
Scenario: User navigate into product listing page, then detail page, click purchase and perform actions. After user purchased, shows purchased successful screen, call Navigator.of(context).popUntil(routeName) back to home screen.
What I want to achieve: After land in home screen, programmatically call api to refresh my balance. Route Observer able to detect navigation back to home screen with didPopNext() method. But this is called no matter it pop from which screen. Therefore the api will repeatedly called which is not ideal. How do I know it was pop from purchased successful screen instead of product listing screen?
Grateful on any helps and hints!
If you where using pop() then you have an option to return some data to previous route but since you are using popUntil() you won't be able to do this. So I think you should clear every route and push home route again from purchased successful page using either pushAndRemoveUntil() or pushNamedAndRemoveUntil(). That means you can now pass an argument to home screen by which you can decide whether to call the API or not.
Navigator.of(context).pushNamedAndRemoveUntil(
'/',
(Route<dynamic> route) => false,
arguments: []
);
Another option would be to figure out a way to return data using popUntil(), Something like this, maybe?

How to clear the navigation stack in Flutter

I want my application to a have Welcome screen, with registration and login option. When I tap on "registration" button to navigate to my Registration screen, i use:
Navigator.push
When I press the "back" button within the Registration screen, it must return to the Welcome page.
But after the user completes the registration I'm using the following code in the Homepage to navigate to my home.
Navigator.pushReplacement
The problem is, when I pressed the "back" button, my app is coming back to the Welcome screen, instead of staying within the Home.
Any idea what is going on?
You can use the following method to clear the navigation stack when you navigate:
Navigator.of(ctx).pushAndRemoveUntil(YourRoute, (Route<dynamic> route) => false);
The second parameter is a Predicate to decide weather the route will be deleted from the stack or not.
Using this method, you'll clear the whole stack before navigating to the route, that way, you won't be able to go back to your Welcome page.