I built an AlertDialog to display Loading while i'm authenticating the user and when it finishes i pop it.
Widget loadingDialog = new AlertDialog(
content: new Row(
children: <Widget>[
new CircularProgressIndicator(),
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: new Text("Loading..."),
),
],
),);
But, if the user taps outside the Dialog it closes. So when the auth finishes, it will still pop something (i guess the scaffol), breaking the app.
How can i make Dialog not closable?
There is a property inside showDialog called barrierDismissible. Setting this value to false will make your AlertDialog not closable by clicking outside.
showDialog(
...
barrierDismissible: false,
...
To prevent dismissing of dialog on press of a back button, you should also wrap your AlertDialog (or any other widget) inside a WillPopScope.
showDialog(
context: context,
barrierDismissible: false, // <-- Set this to false.
builder: (_) => WillPopScope(
onWillPop: () async => false, // <-- Prevents dialog dismiss on press of back button.
child: AlertDialog(...),
),
);
// User Defined Function
void _showloding() {
// flutter defined function
showDialog(
barrierDismissible: false, // JUST MENTION THIS LINE
context: context,
builder: (BuildContext context) {
// return object of type Dialog
return AlertDialog(
content: Padding(
padding: const EdgeInsets.all(20.0),
child: Container(height: 100,width: 100,child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Center(child: SizedBox(height: 50,width: 50,child: CircularProgressIndicator())),
Padding(
padding: const EdgeInsets.only(top: 20),
child: Center(child: Text("Processing")),
)
],
)),
)
);
},
);
}
If you want to prevent dialog close when back button pressed then refer below code. You need to wrap the AlertDialog in WillPopScope widget and make onWillPop property value with function which return Future.value(false).
showDialog(
barrierDismissible: false, //this will prevent popup closing when touch outside of popup
context: context,
builder: (BuildContext context) {
return WillPopScope( // Wrap in WillPopScope widget
onWillPop: () => Future.value(false), //this line will prevent popup closing when back button of phone press
child:AlertDialog(
title: new Text("Alert Title"),
content: new SingleChildScrollView(
child: Container(),),
actions: [
new FlatButton(
child: new Text("Close"),
onPressed: () {
},
),
],
)
)
},
);
Related
I'm creating a function that transfer the text to speech. I want to call it after displaying an alert because it should read the content of the alert.
For now, the function is working juste on clicking a button.
this is the function:
speak(String text) async {
await flutterTts.setLanguage('en-US');
await flutterTts.setPitch(1);
await flutterTts.speak(text);
}
child:
AlertDialog(
contentPadding: EdgeInsets.zero,
clipBehavior: Clip.antiAlias,
content: Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: RichText(
text: TextSpan(
text:
'${view.description}\n'
How can I call this function without pressing any button ?
you can call the speak after showDialog like this:
onTap: () {
showDialog(
context: context,
builder: (BuildContext context) {
return Dialog(
...
);
});
speak();
}
If you are showing Alert as widget you can wrap it whit builder widget like this:
Builder(
builder: (context) {
speak();
return AlertDialog(
...
);
},
),
I have a dialog that appears after user click on send button . When dialog appears , I want to show a text after 5 seconds . I use Future.delayed but the text doesn't appear at all . It appears only when I close the dialog and open it again . I want to show the text after 5 seconds from opening the dialog .
Here is my function
void _initialize() {
Future<void>.delayed(const Duration(seconds: 3), () {
if (mounted) {
setState(() {
visibility = true;
});
}
});
}
}
And here is my dialog code in the onTab of the button
_initialize()
showDialog(context: context,
barrierDismissible: false,
builder: (BuildContext contextd){
return WillPopScope(
onWillPop: () {return Future.value(false);},
child: Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)
),
child: Padding(
padding: EdgeInsets.fromLTRB(20.w, 20.h, 20.w, 20.h),
child: Column(
children: [
//here are some widgets
Visibility(
visible:visibility?true:false,
child: Text("Resend?",style: TextStyle(decoration:
TextDecoration.underline,),)),
],),
),
),
);
});
Try using StatefulBuilder like this:
showDialog(
context: context,
builder: (BuildContext context) => StatefulBuilder(
builder: (context, setState) {
return //somthing to return;
},
));
This happens because your setState that update visibility has a different context than builder dialog. Visibility is actually update but only appear in dialog when close and open again because this is how build dialog is updated. If you want to work with the context dialog need to use that widget:
StatefulBuilder(
builder: (context, setState) {
Into your dialog and then call that setState.
Try using a StatefulBuilder. Using the bool visible and the setDialogState argument, you can update the state of the contents of the dialog.
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return StatefulBuilder(
builder(context, setDialogState) {
// this variable is used for the conditional display
bool visible = false;
// this future will update the visible variable in 3 seconds, after the dialog is displayed already
Future.delayed(Duration(seconds: 3)).then(() => setDialogState(() { visible = true;}));
return WillPopScope(
onWillPop: () { return Future.value(false); },
child: Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)
),
child: Padding(
padding: EdgeInsets.fromLTRB(20.w, 20.h, 20.w, 20.h),
child: Column(
children: [
//here are some widgets
Visibility(
visible:visible,
child: Text(
"Resend?",
style: TextStyle(
decoration: TextDecoration.underline,
),
),
),
],
),
),
),
);
},
);
};
I am using the showDialog function to build a dialog box, but I need to avoid that when the user presses the back button, the dialog box does not close, this is my code:
showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext context) {
// return object of type Dialog
return AlertDialog(
title: new Text("Hello"),
content: new SingleChildScrollView(
child: Container(),
actions: <Widget>[
// usually buttons at the bottom of the dialog
new FlatButton(
child: new Text("Close"),
onPressed: () {
},
),
],
);
},
);
How can I get it to not close?
You need to enclose your AlertDialon on a WillPopScope like this:
showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext context) {
// return object of type Dialog
return WillPopScope(
onWillPop: (){},
child:AlertDialog(
title: new Text("Hello"),
content: new SingleChildScrollView(
child: Container(),),
actions: <Widget>[
// usually buttons at the bottom of the dialog
new FlatButton(
child: new Text("Close"),
onPressed: () {
},
),
],
)
)
},
);
The WillPopScope provides you a onWillPop parameter, where you can pass a function of what you want when the child pop. In this case, the parameter receive an empty function so it wont pop.
You need to use a WillPopScope. It will use the function on onWillPop to determine if the dialog closes or not. In this case always false, so the user can't use the back button to close the dialog.
showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext context) {
// return object of type Dialog
return WillPopScope(
child: AlertDialog(
title: new Text("Hello"),
content: new SingleChildScrollView(
child: Container(),
),
actions: <Widget>[
// usually buttons at the bottom of the dialog
new FlatButton(
child: new Text("Close"),
onPressed: () {
Navigator.of(context).pop();
},
),
],
),
onWillPop: () async {
return false;
},
);
},
);
You can also do it by setting onWillPop: () => Future.value(false) inside WillPopScope. Right now onWillPop:(){} as mentioned in Accepted answer gives warning.
Warning Message: This function has a return type of 'Future', but doesn't end with a return statement.
Try adding a return statement, or changing the return type to 'void'.
So, use onWillPop: () => Future.value(false) or onWillPop: () async {return false;}, instead.
showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext context) {
return WillPopScope(
child: AlertDialog(
................
),
onWillPop: () => Future.value(false),
);
},
);
If you are using Getx Dialog then use like this:
Get.defaultDialog(
titlePadding: EdgeInsets.all(0),
title: "",
barrierDismissible: false,
radius: 10,
onWillPop: () => Future.value(false),
content:Container());
I am trying to have an alert dialogue appear after I click a button but clicking the button doesn't do anything for some reason. I have it in the onPressed so I'm not sure why it isn't triggering. Also if I get this working will it work with Apple devices as well since this is a materials widget.
class AddButton extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
alignment: Alignment.bottomCenter, // align the row
child: Row(
children: <Widget>[
Expanded(
child: RaisedButton(
onPressed: (){
AlertDialog(
title: Text("Test"),
content: Text("This is a test..."),
elevation: 24.0,
);
},
color: Colors.blue,
splashColor: Colors.white,
elevation: 2,
)
)
],
)
)
);
}
}
You have to use the showDialog method to make a dialog appear. Inside the builder callback, you then define the type of dialog you want ex. AlertDialog.
Example (from https://medium.com/#nils.backe/flutter-alert-dialogs-9b0bb9b01d28):
//your method
void _showDialog(BuildContext context) {
// flutter defined function
showDialog(
context: context,
builder: (BuildContext context) {
// return object of type Dialog
return AlertDialog(
title: new Text("Alert Dialog title"),
content: new Text("Alert Dialog body"),
actions: <Widget>[
// usually buttons at the bottom of the dialog
new FlatButton(
child: new Text("Close"),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
Your new code:
onPressed: () => _showDialog(context); // only pass context if you're in a stateless widget
Regarding Apple devices, instead of AlertDialog, you can use CupertinoAlertDialog if you're exclusively developing for iOS.
I want to display some option in the bottom of Flutter AlertDialog. As you can see
If I understand correctly you can use the showDialog component which lays behind the AlertDialog with a nested Column. For a greyed out background ou can use Opacity with a Container:
showDialog(
context: context,
builder: (context) {
return Opacity(
opacity: 0.8, // some opacity
child: Container(
// container to set color
color: Colors.grey,
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
children: [
RaisedButton(
onPressed: null,
), // replace with your buttons
RaisedButton(
onPressed: null,
),
]
)
)
);
}
);
Simple way: you can use padding
showDialog<String>(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return Padding(
padding: const EdgeInsets.only(top:300.0),
child: //AlertDiloag / CupertinoAlertDialog
);
},
);