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.
Related
I want to move to the next page without clicking on button with flutter.
Juste after changing the value of a button, I have to redirect to the next page after some delay without any self interaction.
this is the code :
initialData: BluetoothDeviceState.disconnected,
builder: (c, snapshot) {
if (snapshot.data == BluetoothDeviceState.connected) {
return ElevatedButton(
child: const Text('CONNECTED'),
onPressed: () => Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => MainScreen())),
);
}
You can try this:
if (snapshot.data == BluetoothDeviceState.connected) {
WidgetsBinding.instance.addPostFrameCallback((_) {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => MainScreen()));
});
return Text('CONNECTED');
}
While the connection is depend on bool, you can do
if (snapshot.data == BluetoothDeviceState.connected) {
// a frame delay
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => MainScreen()));
});
}
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
Trying to navigate to a new screen using Navigator.push(), but it's not working.
I have created a custom class to show AlertDialog and call the class with the object to show alertDialog
_customerAlertDialog.showConfirmAlertDialog(
context: context,
title: "Login In",
subTitle: "You need to login to purchase.",
onTapResponse: (bool val) async {
if (val) {
/// close AlertDialog
Navigator.of(context).pop();
Navigator.of(context).push(MaterialPageRoute(builder: (context) => LoginScreen()));
print("show the login screen");
} else {
//TODO : when user click no.
}
});
navigator.pop() is working,
print statement is working,
but Navigator.push is not working. Also tried this:
Navigator.push(context,MaterialPageRoute(builder: (context) => LoginScreen()));
The context object that you use in Navigator.of(context).pop() isn't aware of the dialog.
If your custom alert dialog is calling showDialog, consider passing on the BuildContext object that is returned by the builder:
showDialog(
context: context,
builder: (BuildContext ctx) {
// ctx is a context object that will be aware of the dialog
// consider passing this along to onTapResponse as an argument
},
);
Then you can use that BuildContext to get the navigator that will be able to close the dialog:
onTapResponse: (BuildContext ctx, bool val) async {
if (val) {
// close AlertDialog
Navigator.of(ctx).pop();
Navigator.of(ctx).push(MaterialPageRoute(builder: (context) => LoginScreen()));
print("show the login screen");
} else {
//TODO : when user click no.
}
}
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,)));
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