I'm trying to use a SimpleDialog to select an image from Gallery or Camera but I'm getting the run error type 'SimpleDialog' is not a subtype of type '(() => void)?'
This is my function to call the dialog box
selectImage(context) {
{
return SimpleDialog(
title: Text("Upload Image"),
children: [
SimpleDialogOption(
child: Text("Take Photo"),
onPressed: handleTakePhoto,
),
SimpleDialogOption(
child: Text("Upload From Gallery"),
onPressed: handleChooseFromGallery,
),
SimpleDialogOption(
onPressed: () => Navigator.pop(context),
child: Center(
child: Text("Cancel"),
),
),
],
);
}
}
My handleTakePhoto and handleChooseFromGallery functions are as
handleTakePhoto() async {
Navigator.pop(context);
File file = (await ImagePicker().getImage(
source: ImageSource.camera,
maxHeight: 675.0,
maxWidth: 960,
// imageQuality: 50, //TODO: Look into this
)) as File;
setState(() {
this.file = file;
});
}
handleChooseFromGallery() async {
Navigator.pop(context);
File file = (await ImagePicker().getImage(
source: ImageSource.gallery,
maxWidth: 960,
maxHeight: 675,
preferredCameraDevice: CameraDevice.rear)) as File;
setState(() {
this.file = file;
});
}
Where have I gone wrong?
try to this way implement third dialog
SimpleDialogOption(
onPressed: () { Navigator.pop(context) },
child: Center(
child: Text("Cancel"),
),
),
SimpleDialog needs to be wrap inside showDialog, to get it displayed
Future<void> selectImage() async {
await showDialog(
context: context,
builder: (BuildContext context) {
return SimpleDialog(
title: Text("Upload Image"),
children: [
SimpleDialogOption(
child: Text("Take Photo"),
onPressed: handleTakePhoto,
),
SimpleDialogOption(
child: Text("Upload From Gallery"),
onPressed: handleChooseFromGallery,
),
SimpleDialogOption(
onPressed: () => Navigator.pop(context),
child: Center(
child: Text("Cancel"),
),
),
],
);
});
}
Output:
Related
When I debug on chrome the alert dialog is not showing.
My code:
PopupMenuItem(
value: 1,
onTap: () {
ShowMyDialog();
Navigator.pop(context);
},
child: ListTile(
leading: Icon(Icons.edit),
title: Text("Edit"),
),
),
Future<void> ShowMyDialog() async {
return await showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text("Update"),
content: Container(
child: TextField(
controller: editingController,
),
),
actions: [
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: Text("Cancel"),
),
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: Text("Update"),
),
],
);
},
);
}
Pass context to ShowMyDialog() method. like ShowMyDialog(context);
onTap: () {
ShowMyDialog();
Navigator.pop(context);
},
to
onTap: () {
ShowMyDialog();
},
You were popping the context as soon as the Dialog open so it wasn't showing on that time . now try with this
So I am facing this problem that my alert Dialog isn't displaying. I had tried every possible solution and searching here and there but nothing works. When I click on the edit button from the pop up menu nothing is displayed everything remains the same.
Calling alert Dialog
trailing: PopupMenuButton(
icon: Icon(Icons.more_vert),
itemBuilder: (context)=>[
PopupMenuItem(
value:1,
onTap: (){
//debugPrint('popup');
Navigator.pop(context);
_showMyDialog();
},
child: ListTile(
leading: Icon(Icons.edit),
title: Text('Edit'),
)),
PopupMenuItem(
value:1,
// onTap: (){
// Navigator.pop(context);
// showDialogBox();
// },
child: ListTile(
leading: Icon(Icons.delete),
title: Text('Delete'),
)),
]),
Alert Dialog Code
Future<void> showDialogBox(String title)async{
editController.text=title;
debugPrint('dialog');
return showDialog<void>(
context: context,
barrierDismissible: false,
builder: (BuildContext context){
debugPrint('alert');
return AlertDialog(
title: Text('Update'),
content: Container(
child: TextFormField(
controller: editController,
),
),
actions: [
TextButton(onPressed: (){
Navigator.pop(context);
}, child: Text('Update')),
TextButton(onPressed: (){
Navigator.pop(context);
}, child: Text('Cancel')),
],
);
}
);
}
Complete Class Code
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_database/ui/firebase_animated_list.dart';
import 'package:firebase_tutorial/utils/routes/routes_names.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:firebase_database/firebase_database.dart';
import '../../utils/utils.dart';
class PostScreen extends StatefulWidget {
const PostScreen({Key? key}) : super(key: key);
#override
State<PostScreen> createState() => _PostScreenState();
}
class _PostScreenState extends State<PostScreen> {
final ref=FirebaseDatabase.instance.ref('Post');
FirebaseAuth _auth=FirebaseAuth.instance;
final searchController=TextEditingController();
final editController=TextEditingController();
#override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: ()async{
SystemNavigator.pop();
return true;
},
child: Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
title: Text('Post Screen'),
actions: [
GestureDetector(
onTap: (){
_auth.signOut().then((value){
Navigator.pushNamed(context, RoutesNames.loginScreen);
}).onError((error, stackTrace){
Utils().toastMessage(error.toString());
});
},
child: Icon(Icons.logout_outlined)),
SizedBox(width: 10,),
],
),
floatingActionButton: FloatingActionButton(
onPressed:(){
Navigator.pushNamed(context, RoutesNames.newPost);
},
child: Icon(Icons.add),),
body: Column(
children: [
// Expanded(
// child:FirebaseAnimatedList(
// query: ref,
// itemBuilder: (context,snapshot,animation,index){
// return ListTile(
// title: Text(snapshot.child('post').value.toString()),
// );
// }
// ),
// ),
Padding(
padding: const EdgeInsets.all(10.0),
child: TextFormField(
onChanged: (String value){
setState(() {
});
},
controller: searchController,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: "Search",
),
),
),
Expanded(child: StreamBuilder(
stream: ref.onValue,
builder: (context,AsyncSnapshot<DatabaseEvent> snapshot){
if(!snapshot.hasData){
return CircularProgressIndicator();
}
else{
return ListView.builder(
itemCount: snapshot.data!.snapshot.children.length,
itemBuilder: (context,index){
Map<dynamic,dynamic> map=snapshot.data!.snapshot.value as dynamic;
List<dynamic> list=[];
list.clear();
list=map.values.toList();
final title=list[index]['post'].toString();
if(searchController.text.isEmpty){
return ListTile(
title: Text(list[index]['post']),
subtitle: Text(list[index]['id'].toString()),
trailing: PopupMenuButton(
icon: Icon(Icons.more_vert),
itemBuilder: (context)=>[
PopupMenuItem(
value:1,
onTap: (){
//debugPrint('popup');
Navigator.pop(context);
_showMyDialog();
},
child: ListTile(
leading: Icon(Icons.edit),
title: Text('Edit'),
)),
PopupMenuItem(
value:1,
// onTap: (){
// Navigator.pop(context);
// showDialogBox();
// },
child: ListTile(
leading: Icon(Icons.delete),
title: Text('Delete'),
)),
]),
);
}
else if(title.toLowerCase().contains(searchController.text.toLowerCase())){
return ListTile(
title: Text(list[index]['post']),
subtitle: Text(list[index]['id'].toString()),
);
}
else{
return Container();
}
});
}
}))
],
),
),
);
}
Future<void> showDialogBox(String title)async{
editController.text=title;
debugPrint('dialog');
return showDialog<void>(
context: context,
barrierDismissible: false,
builder: (BuildContext context){
debugPrint('alert');
return AlertDialog(
title: Text('Update'),
content: Container(
child: TextFormField(
controller: editController,
),
),
actions: [
TextButton(onPressed: (){
Navigator.pop(context);
}, child: Text('Update')),
TextButton(onPressed: (){
Navigator.pop(context);
}, child: Text('Cancel')),
],
);
}
);
}
}
try adding a delay before calling showDialog like this:
await Future.delayed(const Duration(milliseconds: 10));
Your dialog isnt displayed because when you select a menu item the pop() method is automatically called to close the popup menu; so if you open a dialog immediately, the dialog will get automatically popped.
hope this fixes your issue
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
I have a bottom navigation bar in a StatefulWidget, and a dialog with 3 options open camera, gallery or cancel.
Here is my code:
navigation bar
Widget build(BuildContext context) {
return new Scaffold(
body: PageView(
children: [
Container(
color: Colors.white,child: HomePage(),),
Container(
color: Colors.white,child: AddPost(),),
],
controller: pageController,
physics: NeverScrollableScrollPhysics(),
onPageChanged: onPageChanged,
),
bottomNavigationBar: CupertinoTabBar(
backgroundColor: Colors.white,
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home,
title: Container(height: 0.0),
backgroundColor: Colors.white),
BottomNavigationBarItem(
icon: Icon(Icons.add_circle,
title: Container(height: 0.0),
)
],
onTap: navigationTapped,
currentIndex: _page,
),
);
}
dialog
File file;
_selectImage( ) async {
return showDialog<Null>(
context: context,
barrierDismissible: false, // user must tap button!
builder: (BuildContext context) {
return SimpleDialog(
title: const Text('Create a Post'),
children: <Widget>[
SimpleDialogOption(
child: const Text('Take a photo'),
onPressed: () async {
Navigator.pop(context);
File imageFile =
await ImagePicker.pickImage(source: ImageSource.camera, maxWidth: 1920, maxHeight: 1200, imageQuality: 80);
setState(() {
file = imageFile;
});
}),
SimpleDialogOption(
child: const Text('Choose from Gallery'),
onPressed: () async {
Navigator.of(context).pop();
File imageFile =
await ImagePicker.pickImage(source: ImageSource.gallery, maxWidth: 1920, maxHeight: 1200, imageQuality: 80);
setState(() {
file = imageFile;
});
}),
SimpleDialogOption(
child: const Text("Cancel"),
onPressed: () {
Navigator.pop(context);
},
)
],
);
},
);
}
I want to do something like this, i can open the dialog but it didn't wait til option is selected
void navigationTapped(int page) async{
if(page != 1){
pageController.jumpToPage(page);
}else{
await _selectImage(); //opens dialog
}
//Handle button tap
}
How can i do to await until option is select by the user on tap the navigation bar?
Thanks in advance!
In your _selectImage function, you can wait the dialog to be closed to do some code like this :
await showDialog(
context: context,
barrierDismissible: false, // user must tap button!
builder: (BuildContext context) {
return SimpleDialog(
title: const Text('Create a Post'),
children: <Widget>[
SimpleDialogOption(
child: const Text('Take a photo'),
onPressed: () async {
Navigator.pop(context);
File imageFile = await ImagePicker.pickImage(source: ImageSource.camera, maxWidth: 1920, maxHeight: 1200, imageQuality: 80);
setState(() {
file = imageFile;
});
}),
SimpleDialogOption(
child: const Text('Choose from Gallery'),
onPressed: () async {
Navigator.of(context).pop();
File imageFile = await ImagePicker.pickImage(source: ImageSource.gallery, maxWidth: 1920, maxHeight: 1200, imageQuality: 80);
setState(() {
file = imageFile;
});
}),
SimpleDialogOption(
child: const Text("Cancel"),
onPressed: () {
Navigator.pop(context);
},
)
],
);
},
).then((onValue) {
if (onValue != null) {
/// Code you want to do
}
});
The onValue can be set using this function :
Navigator.pop(context, valueYouWantToReturn);
If you want to do some code even if onValue is null (Navigator.pop(context)), delete the condition
child: RaisedButton(
color: const Color(0xFF5867DD),
onPressed: (){
updateProfilePic();
},
Widget updateProfilePic(){
return SimpleDialog(
title: const Text('Select any option'),
children: <Widget>[
SimpleDialogOption(
onPressed: () { profileImg = ImagePicker.pickImage(source: ImageSource.gallery)
.whenComplete(() {
setState(() {});
}); },
child: const Text('open gallery'),
),
SimpleDialogOption(
onPressed: () { profileImg = ImagePicker.pickImage(source: ImageSource.camera)
.whenComplete(() {
setState(() {});
}); },
child: const Text('open camera'),
),
],
);
}
I am trying to implement Dialog when the button is pressed.I want to select image from gallery and camera so that i created a dialog to select any option to upload the picture.The issue is when i click the button dialog is not visible.
You need to call showDialog
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text(title),
content: Text(message),
);
});
As mentioned by Figen Güngör You need to call showDialog.
Just want to clarify that it is a Future (function) not a Widget, therefore your code would be like this:
Future updateProfilePic(BuildContext context){
return showDialog(
context: context,
builder : (BuildContext context){
return SimpleDialog(
title: const Text('Select any option'),
children: <Widget>[
SimpleDialogOption(
onPressed: () { profileImg = ImagePicker.pickImage(source: ImageSource.gallery)
.whenComplete(() {
setState(() {});
}); },
child: const Text('open gallery'),
),
SimpleDialogOption(
onPressed: () { profileImg = ImagePicker.pickImage(source: ImageSource.camera)
.whenComplete(() {
setState(() {});
}); },
child: const Text('open camera'),
),
],
);
},
);
}