How to send data back and navigate to a specific screen? [Flutter] - flutter

I have a calendar widget which selects a date in the form of DateTime. I want to send this value using Navigator.pop but i also want to use a MaterialPageRoute which sends the user back to a page. I cannot use Navigator.pop this way :
onPressed: () async{
DateTime send = date;
Navigator.pop(context, MaterialPageRoute(
builder: (context) => DayPageViewExample(date),
)
);
},
because the user will be navigating to the calendar screen in this flow : initial screen => second screen => calendar screen. and the selected date in the calendar must be sent back to the initial screen.
I essentially want something like this:
onPressed: () async{
DateTime send = date;
Navigator.pop(context, send);
},
but i want to send the DateTime send as a parameter to MaterialPageRoute.
Could i get some suggestion on how to refactor the Navigator.pop so that i can send a parameter back using MaterialPageRoute?

I had a similar issue: TabScreen -> TakePhotoScreen -> DisplayPhotoScreen and after the photo was displayed, I wanted to return to the TabScreen with a specific tab selected.
In DisplayScreen I wrapped the main widget with WillPopScope:
body: Center(
child: WillPopScope(
onWillPop: _handleNavigatorPop,
child: ...
)
)
_handleNavigatorPop method shows an alert dialog. On "Yes" action:
actions: <Widget>[
FlatButton(
child: Text("Yes"),
onPressed: () async {
final PageRouteBuilder _route = PageRouteBuilder(
pageBuilder: (BuildContext context, _, __) {
return TabsScreen(tabIndex: tabIndex);
});
//to remove all the routes below the pushed route, use a RoutePredicate that always returns false (e.g. (Route<dynamic> route) => false).
await Navigator.pushAndRemoveUntil(context, _route, (Route<dynamic> r) => false);
return Future.value(false);
},
),
FlatButton(
child: Text("No"),
onPressed: () {
Navigator.of(context).pop();
},
),
]
Read more: pushAndRemoveUntil

For return to first route you can use popUntil - like this:
Navigator.of(context).popUntil((route) => route.isFirst);
But if you want to send result - I think you can use pushReplacement
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (context) => DayPageViewExample(date),
)
);
It will just open new route with closing existing ones
Hope this is what you need

Sounds like you want to do something like this:
Navigator.pushAndRemoveUntil(
MaterialPageRoute(builder: (BuildContext context) => DayPageViewExample(date)),
(Route<dynamic> route) => false),
);
This will remove all the routes below the pushed route.
Read more about pushAndRemoveUntil

Related

Unable to read passed RouteSettings inside popUntil routes - Issue only in Release/Profile

This looks possible duplicate of
Flutter Navigator.popUntil() with ModalRoute.withName() not working in profile and release mode
But it's not.
The above question resolves the issue of mismatched route names, But in my case, RouteSettings is always null.
Issue only for Android and only for Release/Profile builds
// Pushing the route
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) {
return ScreenA();
},
settings: RouteSettings(name: "screenA"),
),
);
// Popping until pushed route
Navigator.of(context).popUntil((route) {
print(route.settings.name);
// Here name and arguments are always null
return route.settings.name == 'screenA';
});
UPDATE
Also tried with pushNamed with specified routes, and onGenerateRoute method. RouteSettings.name and RouteSettings.arguments is always null.
Flutter 1.22.5
I was calling popUntil from inside a dialog. Like below example,
await showDialog(
context: context,
builder: (context) {
return Dialog(
child: Container(
child: RaisedButton(
onPressed: () {
Navigator.of(context).popUntil((route) {
return route.settings.name == 'screenA';
});
},
),
),
);
},
);
And the issue was because of await, Removing it works perfectly fine. If using await before showDialog RouteSettings.name comes null.

I navigate to blank page always in flutter

I'm trying to change screens in my flutter application which is called BMI calculator and the problem is whenever I try to go to new screen it doesn't work and It gives me black empty screen
and the code is
GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return ResultsPage();
}
),);
},
this is the first screen and the following is the second screen
try this:
Navigator.of(context).push(MaterialPageRoute(builder: (context) => ResultsPage()));
onTap: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ResultsPage()),
),
Try like this

Flutter: How do I pop dialog as well as current page?

Below is the code.
Navigation to Login page, from Home page
ElevatedButton(
onPressed: () => Navigator.of(context, rootNavigator: true)
.push(MaterialPageRoute(
fullscreenDialog: true,
builder: (context) => UserLoginPage(),
)),
child: Text('Login to continue'),
),
Inside Login page:
BlocConsumer<UserAuthCubit, UserAuthState>(
listener: (context, state) {
if (state is UserAuthorized) {
Navigator.of(context, rootNavigator: true).pop();
}
if (state is UserAuthWaiting) {
showModalBottomSheet(
useRootNavigator: true,
isDismissible: false,
context: context,
builder: (context) {
return WillPopScope(
onWillPop: () async => false,
child: Center(
child: Text(state.msg),
),
);
});
dialog = true;
} else {
if (dialog) {
Navigator.of(context, rootNavigator: true).pop();
dialog = false;
}
}
},
builder: (context, state) { // some widget code... }
When the state is UserAuthorized, I want to pop the dialog as well as the LoginPage, so as to return to the last page i.e. Home page. However, with the code above, sometimes, it works, and on another time, the Home page is also popped out.
I tried, with/without rootNavigator set to true, but couldn't achieve my objective.
Please help me understand what I'm missing here.
I have checked the answer here How to dismiss flutter dialog?
.
You can simply use
Navigator.popUntil(context, (route) {
return count++ == 2;
});
UPDATE:
If you don't know how many page you should pop then you should use
Navigator.push(context, MaterialPageRoute(builder: (context)=>YourMaterialClassName(), settings: RouteSettings(name: "nameOfYourClass")));
while you push your material class.
then in the time of poping up use
Navigator.popUntil(context, (route) => route.settings.name == "nameOfYourClass");
I suggest after the dialog return true, instead of using Navigator.of(context).pop().
Or you can try using
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (context) => HomePage()),
)
By doing so you replace the LoginPage with HomePage.

Flutter dialog not closing completely

We have a Flutter dialog that when we click Ok and it sends the user home... the dialog lingers on the screen even after sending them home and then goes away which is annoying.
Here is the code for the dialog:
Future<void> _requestSupportDialog(BuildContext context, User user, Features features) {
return showDialog<void>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Success! You have been entered into the support queue'),
content: const Text('Support it on its way'),
actions: <Widget>[
FlatButton(
child: Text('Ok'),
onPressed: () {
// Send them HOME.
Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context) => new FlutterReduxApp(user: user, features: features)));
},
),
],
);
},
);
}
Navigator.of(context, rootNavigator: true).pop();
Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (BuildContext context)=>Home(son: 0,)));
Before pushing to a new route, try to pop first to dismiss the dialog.
Navigator.of(context).pop()
Navigator.of(context, rootNavigator: true).pop();
Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (BuildContext context)=>Home(son: 0,)));

How to open specific screen if user click to back button in flutter?

I have five screens and page routing direction shown as below:
Login -> Home -> Debits -> Payment -> PaymentSuccess
On payment screen if payment success I am opening paymentSuccess screen.
I want to do this:
If user click to back button on PaymentSuccess screen, user should go to HomeScreen.
I used pushAndRemoveUntil shown as below but when user click to back button on PaymentSuccessScreen app closing, not routing to HomeScreen.
// Payment Screen
Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(
builder: (context) {
return PaymentSuccessScreen(period: period);
},
), ModalRoute.withName('/home-screen'));
In Login page, when navigating to Home page, use
Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => HomePage())),
In Home page, when navigating to Debit page, use
Navigator.push(context, MaterialPageRoute(builder: (context) => DebitPage())),
In Debit page, when navigating to Payment page, use
Navigator.push(context, MaterialPageRoute(builder: (context) => PaymentPage())),
And now here in the Payment page, use following:
class PaymentPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Payment")),
body: WillPopScope(
onWillPop: () { // this is the block you need
Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (context) => HomePage()), (route) => false);
return Future.value(false);
},
child: Center(
child: RaisedButton(
child: Text("Go to payment success"),
onPressed: () => Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => PaymentSuccessPage())),
),
),
),
);
}
}