I have a flutter app that has the following drawer:
Routes:
Home: "/"
Nearby: "/nearby"
Applied: "/applied"
The behaviour I want to achieve is when the user clicks the android back button from nearby and applied screens, the app should take them to the home screen. If they press the back button from the home screen again it takes them out of the app.
Just to clarify here if they go to nearby, then to applied then click the back button it should take them to home, not applied.
Here is my code for navigating when nearby and applied drawer items are selected:
Navigator.pushNamedAndRemoveUntil(
context,
routeName,
ModalRoute.withName("/")
);
I expected this to leave the following routes in the stack:
home
selected page
But what I am getting is from nearby or applied screen when I tap the back button on android it takes me out of the app, rather than drop me to the home screen.
What am I missing? How can I achieve the behaviour I'm looking for?
Note that I know there's a solution using WillPopScope widget but I am looking for a solution that uses the navigation stack. More importantly I'm interested to know why the above scenario is not working.
Navigator.of(context).popUntil((route) => route.isFirst);
Add this WllPopCallBack() in NearBy and Apply widgets.
Future<bool> _willPopCallback() async {
Navigator.pushNamedAndRemoveUntil(
context,
routeName,
ModalRoute.withName("/")
);
return false; // return true if the route to be popped
}
Add this WllPopScope widget over Scaffold() in NearBy and Apply widgets like this:
new WillPopScope(child: new Scaffold(), onWillPop: _willPopCallback)
Related
I'm using flutter_typeahead: ^4.3.3 package for search bar.
When the onChange event is dispatched, it will call API and show suggestion on that but it's running one keyword behind the actual search and whenever I try to tap on suggestion it will not navigate to next screen.
I had try to navigate on onSuggestionSelected, onTap and suggestionsCallback but it will not navigate to next screen.
The issue you're facing with flutter_typeahead might be due to incorrect implementation of the onSuggestionSelected or onTap event handlers.
To correctly navigate to the next screen, you need to use the Navigator class in Flutter. Here's an example on how to do it using the onSuggestionSelected event handler:
TypeAheadField(
onSuggestionSelected: (suggestion) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => YourNextScreen(suggestion),
),
);
},
// Other TypeAheadField properties and configurations
)
In the code above, YourNextScreen is the widget class for the next screen you want to navigate to. The suggestion argument is the selected suggestion from the suggestions list.
Make sure to pass the appropriate BuildContext to the Navigator and also ensure that you have set up the routing in your Flutter app.
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()
Is it possible to use a separate Navigator in a pop up window? Separate BuildContext?
I have a working app (APP1) and I would like to show it in a new one (APP2) (e.g. on a button press to open the existing app). APP1 has multiple pages.
I was able add the APP1 as an dependency to APP2 and load the main page in a popup dialog (Alert dialog).
The issue happens when I try to navigate through the APP1. If I click on the button in the APP1 it changes the page in the whole new app.
I would like to have separate navigation in the pop up dialog, so that the included app Navigator works only in the pop-up dialog.
What would be a preferred/possible way to achieve this?
Here is a small example:
Soure code
The example consists of 2 apps (APP1 and APP2). APP2 includes APP1 and shows it in a pop up dialog.
You can add a nested Navigator (if you're using Navigator 1.0 in Flutter) by adding the Navigator widget inside your dialog component, that way you manage the navigation of pages within that dialog itself, create nested routes and navigate only within that navigation stack.
You can do something like:
class NestedDialog extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Navigator(
key: <ADD_UNIQUE_KEY>, // add a unique key to refer to this navigator programmatically
initialRoute: '/',
onGenerateRoute: (RouteSettings settings) {
// here you return your own page widgets wrapped
// inside a PageRouteBuilder
}
)
);
}
}
Then you can even use Flutter's own showDialog and load your custom dialog widget like so:
showDialog(context: context,
barrierDismissible: true,
builder: (BuildContext cxt) {
return AlertDialog(
content: NestedDialog()
);
});
Something along those lines. Give that a shot. Here's a Github Gist you can run on DartPad.dev so you can see what I mean. You don't have to create two apps; just distribute your app into two main widgets, and the child pages go under each main widget's child pages; See gist https://gist.github.com/romanejaquez/d769e6e766fbacb2f5c166dd3bceab51. Run it on DartPad.dev.
Let's say I have two screens A and B .
I am on screen A and I use pushReplacementNamed() to get to screen B.
Now I want to go back to screen A when user swipes right (default in iOS for back button).
Screen A :
Navigator.pushReplacementNamed(context, '/B'),
Screen B :
WillPopScope(
onWillPop: () async {
Navigator.pushReplacementNamed(context, '/A');
return false;
}),
But this is not working. Back button is still disabled.
Note - I don't want to make custom back button in AppBar to achieve this. I want to use the default back button behaviour.
What I think is wrong with your code is that you're returning false from onWillPop, return false disregards the action of the back tap. Try changing that to true.
Also if you want to eventually go back to screen A from screen B it makes more sense to just use a push() on screen A and then on screen B inside onWillPop you no longer need to manually pop the route using navigator, you can just return true.
Update
In response to the your comment below, for what you want to achieve, you can normally push a route when on Home page and then on other pages you could just use pushNamedAndRemoveUntil:
Navigator.of(context).pushAndRemoveUntil("B",ModalRoute.withName('Home'));
It will push the page you want and remove everything until page Home. Since "Home" will now always be the root, you no longer need to override onWillPop and can proceed with a normal pop on back button.
Note: Page "Home" has to already be present in the stack for this to work.
If you want to push and remove everything else from the stack change:
ModelRoute.withName("Home"),
To
(Route<dynamic> route) => false,
I am having trouble launching new screen widget. I have main.dart where I am using bottomNavigationBar and body for ViewPager UI. Now I have 3 bottom tabs and when I go to 2nd tab's view and click on a button to launch another screen/view using:
onTap: () => Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => ViewMyContactList(),
),
)
the new screen replaces the 2nd tab's view, when I go to 3rd tab then come back to 2nd tab, the new screen is gone and 2nd tab's initial screen is back. Also when new screen replaces the 2nd screen's initial view and when I do system back press in Android, the app exits straightaway.
You are trying to do Multiple Navigators with BottomNavigationBar
You can reference this doc for detail https://medium.com/coding-with-flutter/flutter-case-study-multiple-navigators-with-bottomnavigationbar-90eb6caa6dbf
Each tab must keep it'own Page Route, you can use the demo code in doc or
You can use the following two package to help you
https://pub.dev/packages/multi_navigator_bottom_bar
Helps you to build multi-navigator bottom navigation bar more easily.
https://pub.dev/packages/nested_navigators Flutter widget for implementing multiple nested navigators with their own route stacks.