What is Modal's onClose equivalent to Dart/Flutter's Dialog? - dart

I'm trying to refresh my states upon a dialog close, either by submission or on exit by the user pressing outside of the dialog. How will I capture that? Which is equivalent to JS/React's Modal onClose.
showDialog(
context: this.context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Add a custom word'),
content: _renderForm(),
actions: <Widget>[
FlatButton(
child: Text('ADD'),
onPressed: () => (_textController.text.isNotEmpty) ? _addNewPair() : null,
),
],
);
}

You can just add the await keyword before showDialog :
yourMethod () async {
await showDialog(
context: this.context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Add a custom word'),
content: _renderForm(),
actions: <Widget>[
FlatButton(
child: Text('ADD'),
onPressed: () => (_textController.text.isNotEmpty) ? _addNewPair() : null,
),
],
);
}
//here you can continue because your dialog was closed
print("after my dialog was closed");
}
If you want to close youd dialog just use this :
Navigator.of(context).pop();

Related

I'm getting "Looking up a deactivated widget's ancestor is unsafe." Error

I'm trying to delete data from firebase when user click the button.
await context line is problematic!
class SecurityOption extends StatelessWidget {//StatelessWidget
const SecurityOption({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Column(
children: [
Divider(
height: 3,
),
ListTile(
title: Text('security').tr(),
leading: Container(
height: 30,
width: 30,
decoration: BoxDecoration(
color: Colors.red, borderRadius: BorderRadius.circular(5)),
child: Icon(Feather.lock, size: 20, color: Colors.white),
),
trailing: Icon(
Feather.chevron_right,
size: 20,
),
onTap: () => _openDeleteDialog(context),
),
],
);
}
_openDeleteDialog(context) {
return showDialog(
barrierDismissible: true,
context: context,
builder: (context) {
return AlertDialog(
title: Text('Delete data').tr(),
content: Text('Are you sure?').tr(),
actions: [
TextButton(
onPressed: () async {
Navigator.pop(context);
await context //This line is problematic!
.read<SignInBloc>()
.deleteDatafromDatabase()
.then((_) async =>
await context.read<SignInBloc>().userSignout())
.then(
(_) => context.read<SignInBloc>().afterUserSignOut())
.then((_) {
Future.delayed(Duration(seconds: 1)).then((value) =>
nextScreenCloseOthers(context, WelcomePage()));
});
},
child: Text('YES').tr(),
),
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('cancel').tr())
],
);
});
}
}
SignInBloc Class:
class SignInBloc extends ChangeNotifier {
...
...
...
Future deleteDatafromDatabase () async{
FirebaseFirestore _db = FirebaseFirestore.instance;
await _db.collection('x').doc('y').delete();
}
}
When I run the app & click the button, it deletes the data but gives an error.
Exception has occurred.
FlutterError (Looking up a deactivated widget's ancestor is unsafe. At
this point the state of the widget's element tree is no longer stable.
To safely refer to a widget's ancestor in its dispose() method, save a
reference to the ancestor by calling
dependOnInheritedWidgetOfExactType() in the widget's
didChangeDependencies() method.)
Besides, the app is freezing(is not closing). Clicks, swipes, etc. is not working...
How can I solve my problem?
You have identified correctly the problematic code.
The problem is after you pop the Dialog, the dialog's context no longer exists but you are trying to access it.
It is almost always better to not use the context that the Dialog builder provides because it can be dismissed at anytime. Even if you move the Navigator.pop to the end you have the barrierDismissible: true so the dialog can be dismissed and you will not be able to access the context.
You can solve this issue by:
Changing the context name that the dialog builder provides to say dialogContext and use this to pop Navigator.pop(dialogContext) and use the context passed to the _openDeleteDialog for the next operations.
_openDeleteDialog(context) {
return showDialog(
barrierDismissible: true,
context: context,
builder: (dialogContext) { <------- Change this
return AlertDialog(
title: Text('Delete data').tr(),
content: Text('Are you sure?').tr(),
actions: [
TextButton(
onPressed: () async {
Navigator.pop(dialogContext); <----- Use here
await context <--- Keep as is
.read<SignInBloc>()
.deleteDatafromDatabase()
.then((_) async =>
await context.read<SignInBloc>().userSignout())
.then(
(_) => context.read<SignInBloc>().afterUserSignOut())
.then((_) {
Future.delayed(Duration(seconds: 1)).then((value) =>
nextScreenCloseOthers(context, WelcomePage()));
});
},
child: Text('YES').tr(),
),
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('cancel').tr())
],
);
});
}
Pass a Function callback (VoidCallback) to the _openDeleteDialog and call it after the Navigator.pop.
onTap: () => _openDeleteDialog(context, ()async {
await context
.read<SignInBloc>()
.deleteDatafromDatabase()
.then((_) async =>
await context.read<SignInBloc>().userSignout())
.then(
(_) => context.read<SignInBloc>().afterUserSignOut())
.then((_) {
Future.delayed(Duration(seconds: 1)).then((value) =>
nextScreenCloseOthers(context, WelcomePage()));
});
}
),
_openDeleteDialog(context, VoidCallback onDelete) {
return showDialog(
barrierDismissible: true,
context: context,
builder: (context) {
return AlertDialog(
title: Text('Delete data').tr(),
content: Text('Are you sure?').tr(),
actions: [
TextButton(
onPressed: () {
Navigator.pop(context);
onDelete();
},
child: Text('YES').tr(),
),
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('cancel').tr())
],
);
});
}

Show snackbar when item is tapped in bottom sheet

I want to show Snackbar when an item is clicked in the bottom sheet. I tried this.
#override
Widget build(BuildContext defaultContext) {
return Scaffold(
body: Center(
child: RaisedButton(
onPressed: () => showModalBottomSheet(
context: defaultContext,
builder: (BuildContext context) {
return Builder(
builder: (BuildContext builderContext) {
return ListTile(
title: Text("Click me"),
onTap: () {
Navigator.pop(builderContext); // hiding bottom sheet
Scaffold.of(builderContext).showSnackBar(SnackBar(content: Text("Hi")));
},
);
},
);
},
),
),
),
);
}
But I am having error
Scaffold.of() called with a context that does not contain a Scaffold
Note The question is not a duplicate of this
PS: I know I can use GlobalKey in Scaffold to show the Snackbar but I want to do it using Builder like the docs suggest to use Builder. I did use builder and it didn't work.
This worked out finally.
#override
Widget build(BuildContext defaultContext) {
return Scaffold(
body: Center(
child: Builder(builder: (builderContext) {
return RaisedButton(
onPressed: () => showModalBottomSheet(
context: defaultContext,
builder: (BuildContext context) {
return ListTile(
title: Text("Click me"),
onTap: () {
Navigator.pop(builderContext); // hiding bottom sheet
Scaffold.of(builderContext).showSnackBar(SnackBar(content: Text("Hi")));
},
);
},
),
);
},),
),
);
}
I need to move Builder up the tree. Don't know the reason why but it worked.

How to make an AlertDialog in Flutter?

I am learning to build apps in Flutter. Now I have come to alert dialogs. I have done them before in Android and iOS, but how do I make an alert in Flutter?
Here are some related SO questions:
How to style AlertDialog Actions in Flutter
adding dropdown menu in alert dialog box in flutter
Show alert dialog on app main screen load automatically
how to refresh alertdialog in flutter
Alert Dialog with Rounded corners in flutter
I'd like to make a more general canonical Q&A so my answer is below.
One Button
showAlertDialog(BuildContext context) {
// set up the button
Widget okButton = TextButton(
child: Text("OK"),
onPressed: () { },
);
// set up the AlertDialog
AlertDialog alert = AlertDialog(
title: Text("My title"),
content: Text("This is my message."),
actions: [
okButton,
],
);
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
Two Buttons
showAlertDialog(BuildContext context) {
// set up the buttons
Widget cancelButton = TextButton(
child: Text("Cancel"),
onPressed: () {},
);
Widget continueButton = TextButton(
child: Text("Continue"),
onPressed: () {},
);
// set up the AlertDialog
AlertDialog alert = AlertDialog(
title: Text("AlertDialog"),
content: Text("Would you like to continue learning how to use Flutter alerts?"),
actions: [
cancelButton,
continueButton,
],
);
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
Three Buttons
showAlertDialog(BuildContext context) {
// set up the buttons
Widget remindButton = TextButton(
child: Text("Remind me later"),
onPressed: () {},
);
Widget cancelButton = TextButton(
child: Text("Cancel"),
onPressed: () {},
);
Widget launchButton = TextButton(
child: Text("Launch missile"),
onPressed: () {},
);
// set up the AlertDialog
AlertDialog alert = AlertDialog(
title: Text("Notice"),
content: Text("Launching this missile will destroy the entire universe. Is this what you intended to do?"),
actions: [
remindButton,
cancelButton,
launchButton,
],
);
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
Handling button presses
The onPressed callback for the buttons in the examples above were empty, but you could add something like this:
Widget launchButton = TextButton(
child: Text("Launch missile"),
onPressed: () {
Navigator.of(context).pop(); // dismiss dialog
launchMissile();
},
);
If you make the callback null, then the button will be disabled.
onPressed: null,
Supplemental code
Here is the code for main.dart in case you weren't getting the functions above to run.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter',
home: Scaffold(
appBar: AppBar(
title: Text('Flutter'),
),
body: MyLayout()),
);
}
}
class MyLayout extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: ElevatedButton(
child: Text('Show alert'),
onPressed: () {
showAlertDialog(context);
},
),
);
}
}
// replace this function with the examples above
showAlertDialog(BuildContext context) { ... }
I used similar approach, but I wanted to
Keep the Dialog code as a widget in a separated file so I can reuse it.
Blurr the background when the dialog is shown.
Code:
1. alertDialog_widget.dart
import 'dart:ui';
import 'package:flutter/material.dart';
class BlurryDialog extends StatelessWidget {
String title;
String content;
VoidCallback continueCallBack;
BlurryDialog(this.title, this.content, this.continueCallBack);
TextStyle textStyle = TextStyle (color: Colors.black);
#override
Widget build(BuildContext context) {
return BackdropFilter(
filter: ImageFilter.blur(sigmaX: 6, sigmaY: 6),
child: AlertDialog(
title: new Text(title,style: textStyle,),
content: new Text(content, style: textStyle,),
actions: <Widget>[
new FlatButton(
child: new Text("Continue"),
onPressed: () {
continueCallBack();
},
),
new FlatButton(
child: Text("Cancel"),
onPressed: () {
Navigator.of(context).pop();
},
),
],
));
}
}
You can call this in main (or wherever you want) by creating a new method like:
_showDialog(BuildContext context)
{
VoidCallback continueCallBack = () => {
Navigator.of(context).pop(),
// code on continue comes here
};
BlurryDialog alert = BlurryDialog("Abort","Are you sure you want to abort this operation?",continueCallBack);
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
You can use this code snippet for creating a two buttoned Alert box,
import 'package:flutter/material.dart';
class BaseAlertDialog extends StatelessWidget {
//When creating please recheck 'context' if there is an error!
Color _color = Color.fromARGB(220, 117, 218 ,255);
String _title;
String _content;
String _yes;
String _no;
Function _yesOnPressed;
Function _noOnPressed;
BaseAlertDialog({String title, String content, Function yesOnPressed, Function noOnPressed, String yes = "Yes", String no = "No"}){
this._title = title;
this._content = content;
this._yesOnPressed = yesOnPressed;
this._noOnPressed = noOnPressed;
this._yes = yes;
this._no = no;
}
#override
Widget build(BuildContext context) {
return AlertDialog(
title: new Text(this._title),
content: new Text(this._content),
backgroundColor: this._color,
shape:
RoundedRectangleBorder(borderRadius: new BorderRadius.circular(15)),
actions: <Widget>[
new FlatButton(
child: new Text(this._yes),
textColor: Colors.greenAccent,
onPressed: () {
this._yesOnPressed();
},
),
new FlatButton(
child: Text(this._no),
textColor: Colors.redAccent,
onPressed: () {
this._noOnPressed();
},
),
],
);
}
}
To show the dialog you can have a method that calls it NB after importing BaseAlertDialog class
_confirmRegister() {
var baseDialog = BaseAlertDialog(
title: "Confirm Registration",
content: "I Agree that the information provided is correct",
yesOnPressed: () {},
noOnPressed: () {},
yes: "Agree",
no: "Cancel");
showDialog(context: context, builder: (BuildContext context) => baseDialog);
}
OUTPUT WILL BE LIKE THIS
Here is a shorter, but complete code.
If you need a dialog with only one button:
await showDialog(
context: context,
builder: (context) => new AlertDialog(
title: new Text('Message'),
content: Text(
'Your file is saved.'),
actions: <Widget>[
new FlatButton(
onPressed: () {
Navigator.of(context, rootNavigator: true)
.pop(); // dismisses only the dialog and returns nothing
},
child: new Text('OK'),
),
],
),
);
If you need a dialog with Yes/No buttons:
onPressed: () async {
bool result = await showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text('Confirmation'),
content: Text('Do you want to save?'),
actions: <Widget>[
new FlatButton(
onPressed: () {
Navigator.of(context, rootNavigator: true)
.pop(false); // dismisses only the dialog and returns false
},
child: Text('No'),
),
FlatButton(
onPressed: () {
Navigator.of(context, rootNavigator: true)
.pop(true); // dismisses only the dialog and returns true
},
child: Text('Yes'),
),
],
);
},
);
if (result) {
if (missingvalue) {
Scaffold.of(context).showSnackBar(new SnackBar(
content: new Text('Missing Value'),
));
} else {
saveObject();
Navigator.of(context).pop(_myObject); // dismisses the entire widget
}
} else {
Navigator.of(context).pop(_myObject); // dismisses the entire widget
}
}
Simply used this custom dialog class which field you not needed to leave it or make it null so this customization you got easily.
import 'package:flutter/material.dart';
class CustomAlertDialog extends StatelessWidget {
final Color bgColor;
final String title;
final String message;
final String positiveBtnText;
final String negativeBtnText;
final Function onPostivePressed;
final Function onNegativePressed;
final double circularBorderRadius;
CustomAlertDialog({
this.title,
this.message,
this.circularBorderRadius = 15.0,
this.bgColor = Colors.white,
this.positiveBtnText,
this.negativeBtnText,
this.onPostivePressed,
this.onNegativePressed,
}) : assert(bgColor != null),
assert(circularBorderRadius != null);
#override
Widget build(BuildContext context) {
return AlertDialog(
title: title != null ? Text(title) : null,
content: message != null ? Text(message) : null,
backgroundColor: bgColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(circularBorderRadius)),
actions: <Widget>[
negativeBtnText != null
? FlatButton(
child: Text(negativeBtnText),
textColor: Theme.of(context).accentColor,
onPressed: () {
Navigator.of(context).pop();
if (onNegativePressed != null) {
onNegativePressed();
}
},
)
: null,
positiveBtnText != null
? FlatButton(
child: Text(positiveBtnText),
textColor: Theme.of(context).accentColor,
onPressed: () {
if (onPostivePressed != null) {
onPostivePressed();
}
},
)
: null,
],
);
}
}
Usage:
var dialog = CustomAlertDialog(
title: "Logout",
message: "Are you sure, do you want to logout?",
onPostivePressed: () {},
positiveBtnText: 'Yes',
negativeBtnText: 'No');
showDialog(
context: context,
builder: (BuildContext context) => dialog);
Output:
Or you can use RFlutter Alert library for that. It is easily customizable and easy-to-use. Its default style includes rounded corners and you can add buttons as much as you want.
Basic Alert:
Alert(context: context, title: "RFLUTTER", desc: "Flutter is awesome.").show();
Alert with Button:
Alert(
context: context,
type: AlertType.error,
title: "RFLUTTER ALERT",
desc: "Flutter is more awesome with RFlutter Alert.",
buttons: [
DialogButton(
child: Text(
"COOL",
style: TextStyle(color: Colors.white, fontSize: 20),
),
onPressed: () => Navigator.pop(context),
width: 120,
)
],
).show();
You can also define generic alert styles.
*I'm one of developer of RFlutter Alert.
Minumum code for alert dialog
showDialog(
context: context,
builder: (_) => AlertDialog(
title: Text('Title'),
content: Text(
'Content widget',
),
),
);
If you want beautiful and responsive alert dialog then you can use flutter packages like
rflutter alert ,fancy dialog,rich alert,sweet alert dialogs,easy dialog & easy alert
These alerts are good looking and responsive. Among them rflutter alert is the best. currently I am using rflutter alert for my apps.
showAlertDialog(BuildContext context, String message, String heading,
String buttonAcceptTitle, String buttonCancelTitle) {
// set up the buttons
Widget cancelButton = FlatButton(
child: Text(buttonCancelTitle),
onPressed: () {},
);
Widget continueButton = FlatButton(
child: Text(buttonAcceptTitle),
onPressed: () {
},
);
// set up the AlertDialog
AlertDialog alert = AlertDialog(
title: Text(heading),
content: Text(message),
actions: [
cancelButton,
continueButton,
],
);
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
called like:
showAlertDialog(context, 'Are you sure you want to delete?', "AppName" , "Ok", "Cancel");
Check out Flutter Dropdown Banner to easily alert users of events and prompt action without having to manage the complexity of presenting, delaying, and dismissing the component.
To set it up:
import 'packages:dropdown_banner/dropdown_banner.dart';
...
class MainApp extends StatelessWidget {
...
#override
Widget build(BuildContext context) {
final navigatorKey = GlobalKey<NavigatorState>();
...
return MaterialApp(
...
home: DropdownBanner(
child: Scaffold(...),
navigatorKey: navigatorKey,
),
);
}
}
To use it:
import 'packages:dropdown_banner/dropdown_banner.dart';
...
class SomeClass {
...
void doSomethingThenFail() {
DropdownBanner.showBanner(
text: 'Failed to complete network request',
color: Colors.red,
textStyle: TextStyle(color: Colors.white),
);
}
}
Click here to see an example
Just to add to the great answers - the best package I found is:
adaptive_dialog: ^1.8.0+1
For a one OK button the best thing I found is using showOkAlertDialog
Implementation:
import 'package:adaptive_dialog/adaptive_dialog.dart';
import 'package:flutter/material.dart';
Widget build(BuildContext context) {
return Container(
child: Center(
child: IconButton(
icon: Icon(
Icons.info,
),
onPressed: () => showOkAlertDialog(
context: context,
okLabel: 'OK',
title: 'Title',
message: 'This is the message',
),
)),
);
}
Clean and dismisses when you click 'Ok'.
If you need a dialog so this code for you. just use showDialog() onPress or any inside a function.
void showDialog() {
showDialog(
context: context,
builder: (ctx) => AlertDialog(
title: const Text("Login Failed!"),
content: const Text(
"Invalid credential !! Please check your email or password",
style: TextStyle(fontSize: 18, fontWeight: FontWeight.w400),
),
actions: <Widget>[
TextButton(
onPressed: () {
Navigator.of(ctx).pop();
},
child: Container(
child: const Text(
"Try again",
style: TextStyle(color: Colors.cyan, fontSize: 17),
),
),
),
],
),
)}
Demo dialog screenshots
hope its helpful๐Ÿ˜Š๐Ÿ˜Š๐Ÿ˜Š
Simple and working solution that I used: Enjoy
// Sample can be used for exit dialog box on apps
showAlertDialog(BuildContext context) {
Widget okButton = TextButton(
child: const Text("Leave now",style: TextStyle(color: Colors.red),),
onPressed: () { SystemNavigator.pop(); },
);
Widget nopeButton = TextButton(
child: const Text("Stay here"),
onPressed: () { Navigator.pop(context); },
);
AlertDialog alert = AlertDialog(
title: const Text("Leave"),
content: const Text("Are you sure you want to leave?"),
actions: [
nopeButton,
okButton,
],
);
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
Another easy option to show Dialog is to use stacked_services package
_dialogService.showDialog(
title: "Title",
description: "Dialog message Tex",
);
});
This code works and demonstrates how to obtain the button value pressed by the user:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'Flutter Code Sample';
#override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: Scaffold(
appBar: AppBar(title: const Text(_title)),
body: const Center(
child: MyStatelessWidget(),
),
),
);
}
}
class MyStatelessWidget extends StatelessWidget {
const MyStatelessWidget({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return TextButton(
onPressed: () {
// set up the buttons
Widget cancelButton = TextButton(
child: Text("Cancel"),
onPressed: () => Navigator.pop(context, 'Cancel'),
);
Widget continueButton = TextButton(
child: Text("Ok"),
onPressed: () => Navigator.pop(context, 'Ok'),
);
showDialog<String>(
context: context,
builder: (BuildContext context) => AlertDialog(
title: const Text('AlertDialog Title'),
content: const Text('AlertDialog description'),
actions: <Widget>[
cancelButton,
continueButton,
],
),
).then((value) => print(value));
},
child: const Text('Show Dialog'),
);
}
}
Pressing on Ok button. then on Cancel button print
`showDialog<String>(
context: context,
builder: (BuildContext context) =>
AlertDialog(
title: const Text(
'Invalid Password',
style: TextStyle(color: Colors.red),
),
content:
const Text('Create Strong Password'),
actions: <Widget>[
Center(
child: TextButton(
style: TextButton.styleFrom(
primary: Colors.white,
backgroundColor: Colors
.red, // Background Color
),
onPressed: () => Navigator.pop(
context, 'Cancel'),
child: const Text('Cancel'),
),
),
],
),
),`

How to display iOS/cupertino alert dialog in Android using Flutter?

I was trying to display a iOS themed dialog box in my Flutter app, but I was unable to find anything in the docs
The keyword for Android theme/style is Material (default design), the keyword for iOS theme/style is Cupertino. Every iOS theme widget has the prefix Cupertino. So that, for you requirement, we can guess the keyword is CupertinoDialog/CupertinoAlertDialog
You can refer here for all of them https://flutter.io/docs/reference/widgets/cupertino
new CupertinoAlertDialog(
title: new Text("Dialog Title"),
content: new Text("This is my content"),
actions: <Widget>[
CupertinoDialogAction(
isDefaultAction: true,
child: Text("Yes"),
),
CupertinoDialogAction(
child: Text("No"),
)
],
)
First you check if platForm ios or android .. then return widget for the current device ..
Future<bool> showAlertDialog({
#required BuildContext context,
#required String title,
#required String content,
String cancelActionText,
#required String defaultActionText,
}) async {
if (!Platform.isIOS) {
return showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text(title),
content: Text(content),
actions: <Widget>[
if (cancelActionText != null)
FlatButton(
child: Text(cancelActionText),
onPressed: () => Navigator.of(context).pop(false),
),
FlatButton(
child: Text(defaultActionText),
onPressed: () => Navigator.of(context).pop(true),
),
],
),
);
}
// todo : showDialog for ios
return showCupertinoDialog(
context: context,
builder: (context) => CupertinoAlertDialog(
title: Text(title),
content: Text(content),
actions: <Widget>[
if (cancelActionText != null)
CupertinoDialogAction(
child: Text(cancelActionText),
onPressed: () => Navigator.of(context).pop(false),
),
CupertinoDialogAction(
child: Text(defaultActionText),
onPressed: () => Navigator.of(context).pop(true),
),
],
),
);
}
I used CupertinoAlertDialog inside the ShowDialog, you can find the same below
showDialog(
context: context,
builder: (BuildContext context) => CupertinoAlertDialog(
title: new Text("Dialog Title"),
content: new Text("This is my content"),
actions: <Widget>[
CupertinoDialogAction(
isDefaultAction: true,
child: Text(StringConstants.BIOMETRICAUTHORIZED),
),
CupertinoDialogAction(
child: Text("No"),
)
],
)
);

Need to close a Modal Bottom Sheet that contains a SimpleDialog flutter

I need a way to close a Modal Bottom Sheet when an action is performed on the SimpleDialog, I have something like this:
Widget _getActionsMenu() {
return Container(
padding: EdgeInsets.fromLTRB(0.0, 0.0, 10.0, 0.0),
child: IconButton(
icon: Icon(Icons.arrow_forward_ios),
color: Colors.grey[400],
onPressed: () {
showModalBottomSheet<void>(
context: context,
builder: (BuildContext context) {
return new Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new ListTile(
leading: new Icon(Icons.train),
title: new Text(Utility.format(
Language.of(context).takePlace, [_place.title])),
onTap: () {
showUserStatusDialog<DialogActions>(
context: context,
child: this._getCurrentUserPlaceStatus());
},
),
new ListTile(
leading: new Icon(Icons.share),
title: new Text(Language.of(context).share),
onTap: () {
Share.share(Utility.format(
Language.of(context).placeInvitation,
[_place.title, 'GooglePlay']));
},
),
],
);
});
},
));
}
Widget _getCurrentUserPlaceStatus() {
//Here are an API call to get some data, we will name this variable as data
var data = getAPIData();
if (data == null) return null; //Also here I need a way to not show the modal and close the modal bottom sheet
return SimpleDialog(
title: Text(data['getCurrentUserPlaceStatus']['status'] == 2
? 'You are going to '
: 'You are in ' +
data['getCurrentUserPlaceStatus']['place']['name']),
children: <Widget>[
FlatButton(
child: Text(Language.of(context).no),
onPressed: () {
Navigator.pop(context, DialogActions.cancel);
}),
FlatButton(
child: Text(Language.of(context).yes),
onPressed: () {
Navigator.pop(context, DialogActions.agree);
})
],
);
}
void showUserStatusDialog<T>({BuildContext context, Widget child}) {
showDialog<T>(
context: context,
builder: (BuildContext context) => child,
).then<void>((T value) {
if (value != null) {
//Here I need to close the Modal Bottom
}
});
}
I need to close the modal bottom when an action is performed in the Simple Dialog, but also, when the return is null, I need to not display a simple modal(I mean just ignore the action) and close the modal bottom sheet.
I will appreciate any feedback.
Solution is just set Navigator.pop(context, DialogActions.cancel); in else case, and return Container();
And into showUserStatusDialog, into the then, use this Navigator.pop(context);

Resources