Flutter AlertDialog Navigator pop black screen issue - android

I have a strange problem with AlertDialog in flutter to dismiss the dialog. I was using the below code snippet to close the dialog as mentioned in the flutter documentation.
Navigator.of(dialogContext).pop();
But show how it doesn`t work and make the app into the inactive mode and turns into the black screen window. To make it work again, i have to kill the app and restart again.
Here is the complete code for alertdialog in flutter
Future<Null> _showDialogContactDial(context, Contact contactRecord) async {
return showDialog<Null>(
context: context,
barrierDismissible: true, // user must tap button!
builder: (BuildContext dialogContext) {
return new AlertDialog(
title: new Text('Confirm Number'),
content: new SingleChildScrollView(
child: new ListBody(
children: <Widget>[
new TextFormField(
maxLines: 1,
decoration: new InputDecoration(hintText: 'Number'),
keyboardType: TextInputType.number,
autofocus: false,
initialValue: contactRecord.phoneNumber.number,
),
],
),
),
actions: <Widget>[
new FlatButton(
child: new Text(
'Call',
style: TextStyle(color: Colors.black),
),
onPressed: () {
Navigator.of(dialogContext).pop();
_launchURL(
context);
},
),
new FlatButton(
color: Colors.red,
child: new Text('Close', style: TextStyle(color: Colors.white)),
onPressed: () {
Navigator.of(dialogContext).pop();
},
),
],
);
},
);
}
I also noticed that it works for one button "call" without any issues but not for the cancel alert dialog as you see in the same code snippet in both button actions.
Help would be appreciated.

Just add rootNavigator:true
Navigator.of(dialogcon, rootNavigator: true).pop();

This worked in my application , i have made little changes in your code ,hope this might help , if this doesn't help you then I think here is a problem in _launchURl method.
void _showDialogContactDial(BuildContext context, Contact contactRecord){
showDialog<Null>(
context: context,
barrierDismissible: true, // user must tap button!
builder: (BuildContext dialogContext) {
return new AlertDialog(
title: new Text('Confirm Number'),
content: new SingleChildScrollView(
child: new ListBody(
children: <Widget>[
new TextFormField(
maxLines: 1,
decoration: new InputDecoration(hintText: 'Number'),
keyboardType: TextInputType.number,
autofocus: false,
initialValue: contactRecord.phoneNumber.number,
),
],
),
),
actions: <Widget>[
new FlatButton(
child: new Text(
'Call',
style: TextStyle(color: Colors.black),
),
onPressed: () {
Navigator.of(dialogContext).pop();
_launchURL(
context);
},
),
new FlatButton(
color: Colors.red,
child: new Text('Close', style: TextStyle(color: Colors.white)),
onPressed: () {
Navigator.of(dialogContext).pop();
},
),
],
);
},
);
}
Use this method as a callback for onTap or wherever you are using it.

Inside your dialog. Surround your flatbuttons with Builder.
Builder(
builder: (context) => FlatButton(
child: Text('Cancelar'),
onPressed: () {
Navigator.of(context).pop();
},
),
),

Related

I want to create bottom sheet dialog like this image below in flutter

Please help me!!!
I m new in flutter, i want to create like this in my flutter app on button click.
Try below code,
showModalBottomSheet(
context: context,
builder: (BuildContext cntx) {
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
leading: Icon(Icons.camera),
title: Text("Camera"),
onTap: () async {
},
),
ListTile(
leading: Icon(Icons.image),
title: Text("Files")),
onTap: () async {
},
),
Container(
height: 50,
color: prefix0.appBackgroundColcor,
child: ListTile(
title: Center(
child: Text(
"Cancel",
style: TextStyle(color: Colors.white),
),
),
onTap: () {
Navigator.pop(context);
},
),
)
],
);
});
You can use cupertino bottom modal to achieve something like that. See below code for implementation:
void show() {
showCupertinoModalPopup(
context: context,
builder: (BuildContext cont) {
return CupertinoActionSheet(
actions: [
CupertinoActionSheetAction(
onPressed: () {
print('Camera');
},
child: Text('Use Camera'),
),
CupertinoActionSheetAction(
onPressed: () {
print('Upload files');
},
child: Text('Upload from files'),
),
CupertinoActionSheetAction(
onPressed: () {
print('Dropbox');
},
child: Text('Upload from DropBox'),
)
],
cancelButton: CupertinoActionSheetAction(
onPressed: () {
Navigator.of(cont).pop;
},
child: Text('Cancel', style: TextStyle(color: Colors.red)),
),
);
});
}
Call the show function with the press of any button. You will see something like this.
If you don't want the divider between actions you have to create your own custom popup.

Custom Dialog Flutter with many buttons

What I'm trying to do is create a custom dialog with many buttons in flutter,
When user press a button, my goal is to close custom dialog and know which button is pressed (in order to refresh my homepage by using of provider)
I define custom dialog with 2 button (for example). How I can achieve my goal?
That is the code:
CustomDialog.dart
import 'package:flutter/material.dart';
class CustomDialog extends StatelessWidget {
dialogContent(BuildContext context) {
return Container(
decoration: new BoxDecoration(
color: Colors.white,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Colors.black26,
blurRadius: 10.0,
offset: const Offset(0.0, 10.0),
),
],
),
child: Column(
mainAxisSize: MainAxisSize.min, // To make the card compact
children: <Widget>[
RaisedButton(
onPressed: (){},
child: Text("Button 1"),
),
RaisedButton(
onPressed: (){},
child: Text("Button 2"),
),
],
),
);
}
#override
Widget build(BuildContext context) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
elevation: 0.0,
backgroundColor: Colors.transparent,
child: dialogContent(context),
);
}
}
In main.dart I call it:
Container(
child: Center(
child: RaisedButton(
onPressed: (){
showDialog(context: context,
builder: (BuildContext context){
return CustomDialog(
);
}
);
},
child: Text("Custom Dialog"),
),
),
),
I solved in this way:
showDialog(context: context,
builder: (BuildContext context){
return CustomDialog(
);
}
).then((value) {
});
And in CustomDialog:
Navigator.pop(context, //** RETURNED VALUE**//);
From the dialog it is possible to return the value back to the place where it was opened
First, you have to wait for the value when you open the dialog
return Container(
child: Center(
child: RaisedButton(
onPressed: () async {
var pressedButtonNumber = await showDialog<int>(
context: context,
builder: (BuildContext context) {
return CustomDialog();
});
print(pressedButtonNumber);
},
child: Text("Custom Dialog"),
),
),
);
}
And then you have to return the value when you close the dialog
RaisedButton(
onPressed: () {
Navigator.of(context).pop(1);
},
child: Text("Button 1"),
),

is it Possible to Implement a Dismissible widget for a button inside a SliverList in flutter

so lets say I have built a sliverlist that looks like this.
return new Container(
child: new CustomScrollView(
scrollDirection: Axis.vertical,
shrinkWrap: false,
slivers: <Widget>[
new SliverPadding(
padding: const EdgeInsets.symmetric(vertical: 2.0),
sliver: new SliverList(
delegate: new SliverChildBuilderDelegate(
(BuildContext context, int index) {
ModelClass class= _List[index];
return new Dismissible(
key: new ObjectKey(_List[index]),
child: ModelCard(class),
onDismissed: (DismissDirection direction) {
setState(() {
_List.removeAt(index);
direction == DismissDirection.endToStart;
});
},
background: new Container(
color: const Color.fromRGBO(183, 28, 28, 0.8),
child: new Center(
child: new Text(
"Item Removed",
style: new TextStyle(color: Colors.white),
),
)),
);
// return new ModelCard(class);
}, childCount: _List.length),
),
),
],
));
and now i have a stateless widget called ModelCard to populate the list like this one
new Container(
padding: EdgeInsets.fromLTRB(80.0, 10.0, 0.0, 0.0),
child: new Text(
"${class.listDescription}",
style: new TextStyle(),
),
),
now I want to have an Icon button to dismiss an item so i added it inside the card
new Container(
padding: EdgeInsets.fromLTRB(350.0, 20.0, 0.0, 0.0),
child: new IconButton(
icon: new Icon(Icons.delete), onPressed: () {}),
),
How would you implement the dismissible widget inside an icon button that dismiss an Item in a list when pressed in flutter?
Ok , there is already a package which do what you need.
https://pub.dartlang.org/packages/flutter_slidable
A Flutter implementation of slidable list item with directional slide
actions that can be dismissed.
Usage:
new Slidable(
delegate: new SlidableScrollDelegate(),
actionExtentRatio: 0.25,
child: new Container(
color: Colors.white,
child: new ListTile(
leading: new CircleAvatar(
backgroundColor: Colors.indigoAccent,
child: new Text('$3'),
foregroundColor: Colors.white,
),
title: new Text('Tile n°$3'),
subtitle: new Text('SlidableDrawerDelegate'),
),
),
actions: <Widget>[
new IconSlideAction(
caption: 'Archive',
color: Colors.blue,
icon: Icons.archive,
onTap: () => _showSnackBar('Archive'),
),
new IconSlideAction(
caption: 'Share',
color: Colors.indigo,
icon: Icons.share,
onTap: () => _showSnackBar('Share'),
),
],
);

flutter: IconButton onPressed didn't get called

I put a list of widget as action in Scaffold appBar, but they didn't respond when I press them, I have a floatingButton in the scene too and it works perfectly.
appBar: new AppBar(
title: new Text(
widget.title,
style: new TextStyle(
fontFamily: 'vazir'
),
),
centerTitle: true,
actions: <Widget>[
new IconButton(
icon: new Icon(Icons.search),
highlightColor: Colors.pink,
onPressed: _onSearchButtonPressed(),
),
],
),
void _onSearchButtonPressed() {
print("search button clicked");
}
even if I put IconButton in a Row or Column widget , not in appBar, it doesn't work again.
Answer:
thanks to siva Kumar, I had a mistake in calling function , we should call it in this way:
onPressed: _onSearchButtonPressed, // without parenthesis.
or this way:
onPressed: (){
_onSearchButtonPressed();
},
please try with my answer it will work.
appBar: new AppBar(
title: new Text(
widget.title,
style: new TextStyle(
fontFamily: 'vazir'
),
),
centerTitle: true,
actions: <Widget>[
new IconButton(
icon: new Icon(Icons.search),
highlightColor: Colors.pink,
onPressed: (){_onSearchButtonPressed();},
),
],
),
void _onSearchButtonPressed() {
print("search button clicked");
}
Bump into the question while searching for other solution.
The answer should be:
onPressed: _onSearchButtonPressed,
Without the () brackets. Since they carry the same signature, there is no need to wrap them around another anonymous / lambda function.
Actually we need to set the VoidCallback for onPressed property, When we tap on icon that VoidCallback is called .
We also set null if we don't need any response.
class PracticeApp extends StatelessWidget {
Widget build(BuildContext context) {
return new Scaffold(
floatingActionButton: new FloatingActionButton(
tooltip: "Add",
child: new Icon(Icons.add),
onPressed: () { setState(); },
),
);
}
}
void setState() {
print("Button Press");
}
We can also directly pass the call back like this
onPressed: () { setState(() { _volume *= 1.1; }); }
Example for null
onPressed: null

How to dismiss an AlertDialog on a FlatButton click?

I have the following AlertDialog.
showDialog(
context: context,
child: new AlertDialog(
title: const Text("Location disabled"),
content: const Text(
"""
Location is disabled on this device. Please enable it and try again.
"""),
actions: [
new FlatButton(
child: const Text("Ok"),
onPressed: _dismissDialog,
),
],
),
);
How can I make _dismissDialog() dismiss said AlertDialog?
Navigator.pop() should do the trick. You can also use that to return the result of the dialog (if it presented the user with choices)
Navigator.of(context, rootNavigator: true).pop('dialog')
worked with me.
Navigator.pop(_)
worked for me, but the Flutter Team's gallery contains an example using:
Navigator.of(context, rootNavigator: true).pop()
which also works, and I am tempted to follow their lead.
If you don't want to return any result, use either of them:
Navigator.of(context).pop();
Navigator.pop(context);
But if you do want to return some result, see this
Example:
showDialog(
context: context,
builder: (_) {
return AlertDialog(
title: Text('Wanna Exit?'),
actions: [
FlatButton(
onPressed: () => Navigator.pop(context, false), // passing false
child: Text('No'),
),
FlatButton(
onPressed: () => Navigator.pop(context, true), // passing true
child: Text('Yes'),
),
],
);
}).then((exit) {
if (exit == null) return;
if (exit) {
// user pressed Yes button
} else {
// user pressed No button
}
});
Generally Navigator.pop(context); works.
But If the application has multiple Navigator objects and dialogBox doesn't close, then try this
Navigator.of(context, rootNavigator: true).pop();
If you want to pass the result call, try
Navigator.pop(context,result);
OR
Navigator.of(context, rootNavigator: true).pop(result);
Navigator.of(dialogContext).pop() otherwise you can close page if you navigated from Master to Detail page
showDialog(
context: context,
builder: (dialogContext) {
return Dialog(
child: Column(
children: [
Text("Content"),
RaisedButton(
onPressed: () => Navigator.of(dialogContext).pop(),
child: Text("Close"),
)
],
),
);
},
);
Example of dismissing alert dialog on flat button click
RaisedButton(
onPressed: () {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('Are you sure?'),
content: Text('Do you want to remove item?'),
actions: <Widget>[
FlatButton(
onPressed: () => Navigator.of(context).pop(false),// We can return any object from here
child: Text('NO')),
FlatButton(
onPressed: () => Navigator.of(context).pop(true), // We can return any object from here
child: Text('YES'))
],
)).then((value) =>
print('Selected Alert Option: ' + value.toString()));
},
child: Text('Show Alert Dialog'),
),
Above code have two unique things which is used to provide callback result of dialog
Navigator.of(context).pop(false) -- return false value when we pressed
NO Navigator.of(context).pop(true) -- return true value when we
pressed YES
Based on these return value, we can perform some operation outside of it or maintain the dialog status value
This works Prefectly
RaisedButton(
child: Text(
"Cancel",
style: TextStyle(color: Colors.white),
),
color: Colors.blue,
onPressed: () => Navigator.pop(context),
),
This worked for me Navigator.of(context, rootNavigator: true).pop('dialog').
Navigator.pop() just closes the current page/screen.
Creating a separate context for Alert Dialog would help.
showDialog(
context: context,
builder: (alertContext) => AlertDialog(
title: const Text("Location disabled"),
content: const Text(
"""Location is disabled on this device. Please enable it and try again."""),
actions: [
new FlatButton(
child: const Text("Ok"),
onPressed: () => Navigator.pop(alertContext),
),
],
),
);
Please use following for code to close dialog
RaisedButton(
onPressed: () { Navigator.of(context).pop();},
child: Text("Close",style: TextStyle(color: Colors.white), ),
color: Colors.black,
)
Use Navigator.pop(context);
Example
showDialog(
context: context,
child: new AlertDialog(
title: const Text("Location disabled"),
content: const Text(
"""
Location is disabled on this device. Please enable it and try again.
"""),
actions: [
new FlatButton(
child: const Text("Ok"),
onPressed: () {
Navigator.pop(context);
},
),
],
),
);
This answer works if you want to pop the dialog and navigate to another view. This part 'current_user_location' is the string the router need to know which view to navigate to.
FlatButton(
child: Text('NO'),
onPressed: () {
Navigator.popAndPushNamed(context, 'current_user_location');
},
),
This enough to dismisss dialog add inside Any callback like onpressed,ontap
Navigator.of(context).pop();
AlertDialog(
title: Center(child: Text("$title")),
insetPadding: EdgeInsets.zero,
titlePadding: EdgeInsets.only(top: 14.0, bottom: 4),
content: Container(
height: 50,
child: TextFormField(
controller: find_controller,
decoration: InputDecoration(
suffixIcon: context.watch<MediaProvider>().isChangeDialog
? IconButton(
onPressed: () {
clearController(find_controller);
},
icon: Icon(Icons.clear))
: null,
border: OutlineInputBorder(
borderSide: BorderSide(color: Colors.deepPurpleAccent)),
hintText: 'Id',
),
onChanged: (val) {
if (val.isNotEmpty)
context.read<MediaProvider>().isChangeDialog = true;
else
context.read<MediaProvider>().isChangeDialog = false;
},
),
),
actions: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(4.0),
child: OutlinedButton(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Align(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
child: Icon(Icons.clear),
),
),
Text("Cancel")
],
),
onPressed: () {
context.read<MediaProvider>().isChangeDialog = false;
//========================this enough to dismisss dialog
Navigator.of(context).pop();
}),
),
Padding(
padding: const EdgeInsets.all(4.0),
child: ElevatedButton(
onPressed: context.watch<MediaProvider>().isChangeDialog
? () {
context.read<MediaProvider>().isChangeDialog = false;
okCallback;
}
: null,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Align(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
child: Icon(Icons.check),
),
),
Text("OK")
],
)),
)
],
),
],
);
pass it in the showDialog
barrierDismissible : true
use get package.
then Get.back() to close Modal
For Closing Dialog
void cancelClick() {
Navigator.pop(context);
}
The accepted answer states how to dismiss a dialog using the Navigator Class. To dismiss a dialog without using Navigator you can set the onPressed event of the button to the following:
setState((){
thisAlertDialog = null;
});
In case the code above is not self-explanatory it is basically setting the Parent AlertDialog of the FlatButton to null, thus dismissing it.

Categories

Resources