Flutter showDialog is not shown on PopupMenuItem tap - flutter

I'm using PopupMenuButton in my application. I want to showDialog on tapping a PopupMenuItem.
My PopupMenuItem:
PopupMenuItem(
child: Text("Show dialog"),
onTap: () {
showDialog(
context: context,
barrierColor: Colors.black26,
builder: (context) => AlertDialog(
...
)
},
),
Also using onSelected inside the PopupMenuButton didn't work.

Thats because onTap of popupMenuItem tries to use Navigator.pop to close the popup but at same time you are trying to show the dialog, So it closes the dialog and leaves the popup so, you can wait till the all the animations or ongoing things complete then show dialog
code: dartPad code
PopupMenuItem(
child: const Text('Item 0'),
onTap: () {
WidgetsBinding?.instance?.addPostFrameCallback((_) {
showCupertinoDialog(
context: context,
builder: (context) {
return CupertinoAlertDialog(
title: const Icon(CupertinoIcons.info_circle),
content: const Text(
'Hello User, Welcome',
textAlign: TextAlign.center,
),
actions: [
CupertinoDialogAction(
isDefaultAction: true,
onPressed: () => Navigator.pop(context),
child: const Text('Thanks'),
),
],
);
});
});
}),

Try this one:
PopupMenuItem(
child: Text("Show dialog"),
onTap: () {
Future<void>.delayed(
const Duration(), // OR const Duration(milliseconds: 500),
() => showDialog(
context: context,
barrierColor: Colors.black26,
builder: (context) => AlertDialog(...),
),
),
},
);

Related

How to close severals showDialogs in flutter

How can I to close all the showDialogs in my aplication? in this case _mostrarDialogConfirmacion is the dialog where i request to the user a confirmation to make a query, cargandoDialog is another dialog where i show a loading message while the query is executing, when the query finish, i want to close the two dialogs and only see the _mostrarDialogMensaje dialog
_mostrarDialogConfirmacion(
mensaje,
BuildContext context,
codLink,
motivo,
) {
return showDialog(
context: context,
builder: (context){
return AlertDialog(
title: const Text(
'Informacion',
textAlign: TextAlign.center,
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget> [
Text(mensaje, textAlign: TextAlign.center),
],
),
actions: <Widget> [
TextButton(
onPressed: () async {
Navigator.of(context).pop();
cargandoDialog(context);
List<dynamic> ingresarReclamo1 = await ingresarReclamo
.ingresarReclamo(codLink, titular, motivo);
// ignore: use_build_context_synchronously
Navigator.of(context).pop();
// ignore: use_build_context_synchronously
_mostrarDialogMensaje(
ingresarReclamo1[0].observaciones,
ingresarReclamo1[0].validado,
context,
);
},
child: const Text('Si')
),
TextButton(
onPressed: ()=> Navigator.of(context).pop(),
child: const Text('No')
),
],
);
}
);
}
you will dismiss first dialog and then you can use whenComplete to dismiss the second dialog
showDialog(
.....
).whenComplete(() => Navigator.of(context).pop())
You can return bool while .pop(boolValue) to check the tap button. Also, the showDialog is a future method, you can use await until it finished and then processed to next dialog. Navigator.of(context).pop() will be used to close recent dialog on this case. As for my understanding about the question, try this example code.
_mostrarDialogConfirmacion(mensaje, BuildContext context, codLink, motivo) {
return showDialog(
context: context,
barrierDismissible: false,
builder: (context) {
return AlertDialog(
title: const Text('Informacion', textAlign: TextAlign.center),
content: Column(
mainAxisSize: MainAxisSize.min,
),
actions: <Widget>[
TextButton(
onPressed: () async {
// Navigator.of(context)
// .pop(); //if you like to close previous one before showing the next dialog
final bool isSi = await showDialog(
barrierDismissible: false,
builder: (context) => AlertDialog(
content: Text("Second Dialog"),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop(true);
},
child: const Text('Si')),
TextButton(
onPressed: () =>
Navigator.of(context).pop(false),
child: const Text('No')),
],
),
context: context);
if (mounted && isSi) {
Navigator.of(context).pop();
await showDialog(
builder: (context) => AlertDialog(
content: Text("_mostrarDialogMensaje")),
context: context);
}
},
child: const Text('Si')),
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: const Text('No')),
],
);
});
}

How to open an AlertDialog in Flutter by Button-Press?

after Button-press, i want to open an AlertDialog, but only if the variable bool showAlert is true.
This is my code until now:
FlatButton(
child: Text("HIER"),
onPressed: () {
return AlertDialog(
title: Text("HI"),
content: Text("Are you there?"),
actions: [
FlatButton(child: Text("Yes"), onPressed: () {},),
FlatButton(child: Text("No"), onPressed: () {},)
],
elevation: 24,
);
},
),
For my question (opening the alert if bool is true), the problem is, the AlertDialog is not opening.
Any solutions? Thanks
To show an AlertDialog you need a showDialog, so the code results like this :
FlatButton(
child: Text("HIER"),
onPressed: () {
if(showAlert){
showDialog(
//if set to true allow to close popup by tapping out of the popup
barrierDismissible: false,
context: context,
builder: (BuildContext context) => AlertDialog(
title: Text("HI"),
content: Text("Are you there?"),
actions: [
FlatButton(child: Text("Yes"), onPressed: () {},),
FlatButton(child: Text("No"), onPressed: () {},)
],
elevation: 24,
),
);
}
},
),
Use this code to show native diolog depends on platform:
FlatButton(
child: Text("HIER"),
onPressed: () {
if (Platform.isIOS) {
showCupertinoDialog(
context: context,
builder: (context) {
return CupertinoAlertDialog(
title: Text("HI"),
content: Text("Are you there?"),
actions: [
CupertinoDialogAction(
child: Text("Yes"),
onPressed: () {},
),
CupertinoDialogAction(
child: Text("No"),
onPressed: () {},
)
],
);
},
);
} else {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text("HI"),
content: Text("Are you there?"),
actions: [
FlatButton(
child: Text("Yes"),
onPressed: () {},
),
FlatButton(
child: Text("No"),
onPressed: () {},
)
],
elevation: 24,
);
},
);
}
},
);
Check out this code, Hope it will help you
openDialog(bool showAlert, BuildContext context) async {
if(!showAlert) return;
var result = await showDialog(
context: context,
builder: (BuildContext context) => AlertDialog(
title: Text("HI"),
content: Text("Are you there?"),
actions: [
FlatButton(child: Text("Yes"), onPressed: () {
Navigator.pop(context, true);
},),
FlatButton(child: Text("No"), onPressed: () {
Navigator.pop(context, false);
},)
],
elevation: 24,
),
);
if(!(result ?? false)) {
// Yes click
} else {
// No click
}
}
Alternative
GetX Package Get.dialog()
And for many other scaffold components.
Dialog, Bottosheet, Snackbar, StateManagent Getx and Obx builder, and much more.
Visit pub.dev and search for GetX

AlertDialog not closing Flutter

my button code is as below and previously it closed the AlertDialog + Signed Out of Google when clicking on the continue button, but now it only signs out, the AlertDialog is still there... Anyone knows whats going on?
showAlertDialog(BuildContext context) {
// set up the buttons
Widget cancelButton = FlatButton(
child: Text("Cancel"),
onPressed: () {
Navigator.of(context, rootNavigator: true).pop();
},
);
Widget continueButton = FlatButton(
child: Text("Confirm Sign Out"),
onPressed: () {
signOutGoogle();
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (context) {
return LoginPage();
}), ModalRoute.withName('/'));
},
);
// set up the AlertDialog
AlertDialog alert = AlertDialog(
title: Text("Confirmation"),
content: Text("Are you sure you want to Sign Out?"),
actions: [
cancelButton,
continueButton,
],
);
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
showAlertDialog invoked here :
RaisedButton(
onPressed: () {
showAlertDialog(context);
},
color: Colors.deepPurple,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'Sign Out',
style: TextStyle(fontSize: 25, color: Colors.white),
),
),
elevation: 5,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(40)),
)
Add Navigator.of(context).pop(); after signOutGoogle(); to close the dialog.
showAlertDialog(BuildContext context) {
// set up the buttons
Widget cancelButton = FlatButton(
child: Text("Cancel"),
onPressed: () {
Navigator.of(context, rootNavigator: true).pop();
},
);
Widget continueButton = FlatButton(
child: Text("Confirm Sign Out"),
onPressed: () {
signOutGoogle();
Navigator.of(context).pop(); // Pop the dialog
Navigator.of(context).pushAndRemoveUntil(
MaterialPageRoute(builder: (context) {
return LoginPage();
}), ModalRoute.withName('/'));
},
);
// set up the AlertDialog
AlertDialog alert = AlertDialog(
title: Text("Confirmation"),
content: Text("Are you sure you want to Sign Out?"),
actions: [
cancelButton,
continueButton,
],
);
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}

Alert Dialog on onTap on ListTile

How can I create a AlertDialog by clicking/tapping on ListTile.
Currently I'm doing this and nothing happens when it's clicked.
body: ListView(
children: <Widget>[
ListTile(
title: Text('Theme'),
onTap: (){
AlertDialog(
title: Text('Hi'),
);
},
)
],
),
PS: I'm a noob, please go easy on me.
you are very close, you created the dialog, just need to show it:
body: ListView(
children: <Widget>[
ListTile(
title: Text('Theme'),
onTap: () {
AlertDialog alert = AlertDialog(
title: Text('Hi'),
);
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
},
)
],
),
Change your ListTile with this.
ListTile(
title: Text('Theme'),
onTap: () {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text('Alert Dialog Example'),
content: Text('Alert Dialog Body Goes Here ..'),
actions: <Widget>[
FlatButton(
onPressed: () => Navigator.of(context).pop(),
child: Text('OK')),
],
);
});
},
)
I have also added some properties to use the AlertDialog(), like title, content and actions

show dialog when long pressed and pop it when finger up

I want to show a dialog when user long pressed on an item and pop it when finger up but it can't detect tap up.
I put dialog on another GestureDetector and use onTapUp property of it to pop dialog.
GestureDetector(
child: studentIcon(index, context),
onLongPress: () {
showDialog(
context: context,
builder: (context) {
return GestureDetector(
onTapUp: (detail) {
Navigator.pop(context);
},
child: DialogDetail(
index: index,
),
);
});
},
I expect to pop dialog after finger up after long pressed.
You can't do that as there is an context problem in GestureDetector.
Please follow this answer to implement this thing.
Try to make method to open dialog . i provide alert dialog code..
void _showText(BuildContext context) {
showDialog(
context: context,
barrierDismissible: false,
builder: (context) {
return AlertDialog(
content: Text(
"User name :${nameEditText.text} \nPassword : ${passwordEditText.text}"),
actions: <Widget>[
new FlatButton(
onPressed: () {
Navigator.of(context).pop();
},
child: new Text("OK"))
],
);
});
}
}
after that called on button click..
child: RaisedButton(
padding: EdgeInsets.all(15.0),
onPressed: () {
_showText(context);
},
child: Text(
"Submit",
style: TextStyle(fontSize: 15, color: Colors.white),
),
color: Colors.blue,
),