Flutter: disable the user input while data is uploading - flutter

To prevent errors I want to disable the user input while my flutter app is uploading some data to firebase. I already tried IgnorePointer and AbsorbPointer with a boolean which gets updated via setState when the user presses "upload data". But the user can still enter something on the screen.
Is there a way to disable the user input while the data is uploading? After the upload is finished the user will be navigated automatically in the main menu.
Here are some parts of the code:
class AddJob extends StatefulWidget {
AddJob({Key? key}) : super(key: key);
#override
_AddJobState createState() => _AddJobState();
}
class _AddJobState extends State<AddJob> {
bool ignoring = false;
Future<void> addJob() async {
return showDialog<void>(
barrierDismissible: true,
context: context,
builder: (context) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(15))),
title: Text('Privat oder Öffentlich?'),
content: Text(
'xy'),
actions: <Widget>[
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('back'),
),
TextButton(
onPressed: () async {
setState(() {
ignoring = true;
});
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
duration: Duration(seconds: 4),
content: Row(
children: <Widget>[
new CircularProgressIndicator(),
new Text(" Hochladen...")
],
),
));
... uploading
}
}
#override
Widget build(BuildContext context) {
final _picker = ImagePicker();
return IgnorePointer(
ignoring: ignoring,
child: GestureDetector(
onTap: () {
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}
},
child: Scaffold(
appBar: AppBar(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.vertical(bottom: Radius.circular(15))),
backgroundColor: blueLayerOne,
title: Text('create'),
actions: [
IconButton(
icon: Icon(Icons.info_outline_rounded),
onPressed: () {
showInfos();
}),
],
),
body: SingleChildScrollView(
...normal screen widgets
}
}

Related

how can I make the item made in listview by user clickable into a new page? in flutter

hi I have a page that you can create an item in the listview and give it a name, now I want to when you click on that item, it goes to own dedicated page made with its name on the app bar.
(https://i.stack.imgur.com/5jS0x.png)
here is the listview code:
import 'package:flutter/material.dart';
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
import 'package:attendance/insideList.dart';
class lists extends StatefulWidget {
const lists({super.key});
#override
State<lists> createState() => _listsState();
}
class _listsState extends State<lists> {
List<String> _items = [];
late TextEditingController _textController;
#override
void initState() {
super.initState();
_textController = TextEditingController();
}
#override
void dispose() {
_textController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
_items.sort();
return Scaffold(
body: _items.length > 0
? ListView.separated(
itemCount: _items.length,
itemBuilder: (_, index) {
return ListTile(
leading: const Icon(Icons.school),
trailing: const Icon(Icons.arrow_forward),
title: Center(child: Text('${_items[index]}')),
**//here the attempt I made that didnt work**
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: ((context) => InsideList(index))));
},
onLongPress: (() async {
await showDialog(
context: context,
builder: ((context) {
return AlertDialog(
title: const Text(
"Are you sure you want to delete this class?",
style: TextStyle(fontSize: 15),
),
actions: [
TextButton(
child: Text("cancel"),
onPressed: (() {
Navigator.pop(context);
})),
TextButton(
child: Text('Delete'),
onPressed: () {
setState(() {
_items.removeAt(index);
Navigator.pop(context);
});
},
),
],
);
}));
}),
);
},
separatorBuilder: (BuildContext context, int index) =>
const Divider(
color: Colors.black,
),
)
: const Center(
child: Text("You currently have no classes. Add from below."),
),
floatingActionButton: SpeedDial(
animatedIcon: AnimatedIcons.menu_arrow,
spacing: 6,
spaceBetweenChildren: 6,
backgroundColor: const Color.fromARGB(255, 22, 37, 50),
foregroundColor: const Color.fromARGB(255, 255, 255, 255),
children: [
SpeedDialChild(
child: const Icon(Icons.group_add), label: "add student"),
SpeedDialChild(
child: const Icon(Icons.school),
label: "add class",
onTap: () async {
final result = await showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: const Text('Add a new class'),
content: TextField(
controller: _textController,
autofocus: true,
decoration: const InputDecoration(
hintText: "Enter the name of the class."),
),
actions: [
TextButton(
child: Text('Cancel'),
onPressed: () {
Navigator.pop(context);
},
),
TextButton(
child: Text('Add'),
onPressed: () {
Navigator.pop(context, _textController.text);
_textController.clear();
},
),
],
);
},
);
if (result != null) {
result as String;
setState(() {
_items.add(result);
});
}
},
)
],
),
);
}
}
and this is the new dart file I made for the new page:
import 'package:flutter/material.dart';
class InsideList extends StatelessWidget {
final int index;
InsideList(this.index);
List<String> _students = [];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("attendance"),
centerTitle: true,
backgroundColor: const Color.fromARGB(255, 22, 37, 50),
toolbarHeight: 65,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
bottom: Radius.circular(30),
),
),
),
body: _students.length > 0
? Center(child: Text("hi"))
: Center(
child:
Text("You currently have no students. Add from below.")));
}
}
Instead of passing index, you can pass the item itself,
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: ((context) => InsideList(_items[index])),
),
);
},
And
class InsideList extends StatelessWidget {
final String name;
InsideList(this.name); // use key constructor
List<String> _students = [];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("attendance $name"),

How to Change the label of an existing chip in flutter?

I'm using chips in my code when I tap on chip a counter is displayed, I want to update the chip label with when count is added.
Widget returnWidget() {
return InkWell(
child: Chip(
label: Text(temp!),
),
onTap: () {
print(temp);
_showMyDialog();
},
);
}
This is the widget I'm using to add multiple chips.
Future<void> _showMyDialog() async {
return showDialog<void>(
context: context,
barrierDismissible: false, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
scrollable: false,
title: const Text('Add Count'),
content: Container(
height: 50,
width: 50,
alignment: Alignment.center,
padding: const EdgeInsets.all(3),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
AddCount(),
],
),
),
actions: <Widget>[
TextButton(
child: const Text('Cancel'),
onPressed: () {
{
setState(() {
_itemCount = 0;
});
}
Navigator.of(context).pop();
},
),
TextButton(
child: const Text('Add'),
onPressed: () {
if(count==0) {
setState((){
temp = temp! + _itemCount.toString();
Text(temp!);
count++;
});
}
print(text);
},
),
],
);
},
);
}
This is the code block which is showing a counter dialog. I want to update chip label on add.
Hello here I have a solution, I did not see more details about your code but here I did a working solution, the variable you want to update should be located inside the classed where is used but you can also use state management or InheritedWidget to update variables globally:
class App extends StatelessWidget {
const App({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Example(),
);
}
}
class Example extends StatefulWidget {
const Example({Key? key}) : super(key: key);
#override
State<Example> createState() => _ExampleState();
}
class _ExampleState extends State<Example> {
int temp = 0; // declare the variable inside the class you want to update it
Future<void> _showMyDialog() async {
return showDialog<void>(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
scrollable: false,
title: const Text('Add Count'),
content: Container(
height: 50,
width: 50,
alignment: Alignment.center,
padding: const EdgeInsets.all(3),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
// AddCount(),
],
),
),
actions: <Widget>[
TextButton(
child: const Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
},
),
TextButton(
child: const Text('Add'),
onPressed: () {
setState((){
temp = temp += 1; // update the chip UI
});
Navigator.of(context).pop();
},
),
],
);
},
);
}
Widget returnWidget() {
return InkWell(
child: Chip(
label: Text("count $temp"), // <-- new change
),
onTap: () {
print(temp);
_showMyDialog();
},
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.red,
body: Center(
child: Container(
margin: const EdgeInsets.all(32),
child: returnWidget(),
),
),
);
}
}

How to display SnackBar in Flutter?

I want to display a SnackBar in my Flutter app. I have read the docs and copyed it:
The body of my scaffold:
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async => false,
child: Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text("Osztályok"),
leading: Padding(
padding: const EdgeInsets.only(left: 5.0),
child: IconButton(
icon: Icon(Icons.exit_to_app, color: Colors.white70),
onPressed: () {
authService.signOut();
authService.loggedIn = false;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => GoogleSignUp()));
})),
actions: <Widget>[
Padding(
padding: const EdgeInsets.only(right: 5.0),
child: Row(
children: <Widget>[
IconButton(
icon: Icon(Icons.add_circle_outline,
color: Colors.white70),
onPressed: () {
createPopup(context);
}),
// IconButton(
// icon: Icon(Icons.search, color: Colors.black38),
// onPressed: null),
],
)),
],
),
The SnackBarPage class:
class SnackBarPage extends StatelessWidget {
void jelszopress(TextEditingController jelszoController, BuildContext context) async{
var jelszo;
DocumentReference docRef =
Firestore.instance.collection('classrooms').document(globals.getid());
await docRef.get().then((value) => jelszo= (value.data['Jelszo']) );
if (jelszo == jelszoController.text.toString()){
Navigator.push(context,
MaterialPageRoute(builder: (context) => InClassRoom()));
}
else{
Navigator.pop(context);
final snackBar = SnackBar(content: Text('Yay! A SnackBar!'));
Scaffold.of(context).showSnackBar(snackBar);
}
}
Future<String> jelszoba(BuildContext context) {
TextEditingController jelszoController = TextEditingController();
return showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text('Add meg a jelszót'),
content: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(20)),
),
child: TextField(
controller: jelszoController,
decoration: InputDecoration(hintText: "Jelszó")
)
),
actions: <Widget>[
MaterialButton(
elevation: 5.0,
child: Text('Mehet'),
onPressed: () {
jelszopress(jelszoController, context);
},
)]);
}
);
}
var nevek;
var IDS;
SnackBarPage(this.nevek, this.IDS);
#override
Widget build(BuildContext context){
return ListView.builder(
itemCount: nevek.length,
itemBuilder: (context, index) {
return Card(
child: ListTile(
onTap: () {
globals.setid(IDS[index]);
jelszoba(context);
},
title: Text(nevek[index]),
),
);
},
) ;
}
}
But my cody doesn't display the SnackBar. I tried the solution of this question: How to properly display a Snackbar in Flutter? but adding a Builder widget didn't help.
"Scaffold.of(context)" has been deprecated, will return null. Now use "ScaffoldMessenger.of(context)". As per Flutter documentation.
#override
Widget build(BuildContext context) {
// here, Scaffold.of(context) returns null
return Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: const Text('snack'),
duration: const Duration(seconds: 1),
action: SnackBarAction(
label: 'ACTION',
onPressed: () { },
),
));
},
child: const Text('SHOW SNACK'),
),
),
);
}
NOTE: Make sure your main.dart overrided build() function should return "MaterialApp" as a widget, such as:
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
// Must be MaterialApp widget for ScaffoldMessenger support.
return MaterialApp(
title: 'My App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyDashboard(),
);
}
}
So based on the error, it would seem that the context passed in Snackbar.of() is not the correct context. This would make sense based on 1 & 2; and summary copied below:
Each widget has its own BuildContext, which becomes the parent of the widget returned by the StatelessWidget.build or State.build function. (And similarly, the parent of any children for RenderObjectWidgets.)
In particular, this means that within a build method, the build context of the widget of the build method is not the same as the build context of the widgets returned by that build method.
So this means that the build context you are passing in jelszoba(context) function is not the build context you need and is actually the build context of the widget that is instantiating the Scaffold.
So How to Fix:
To fix this wrap your Card widget in your SnackbarPage in a Builder widget and pass the context from it, to the jelszoba(context) method.
An example from 1 I post below:
#override
Widget build(BuildContext context) {
// here, Scaffold.of(context) returns null
return Scaffold(
appBar: AppBar(title: Text('Demo')),
body: Builder(
builder: (BuildContext context) {
return FlatButton(
child: Text('BUTTON'),
onPressed: () {
// here, Scaffold.of(context) returns the locally created Scaffold
Scaffold.of(context).showSnackBar(SnackBar(
content: Text('Hello.')
));
}
);
}
)
);
}
You can normally use snack bar in the Bottom Navigation bar in this way. However, if you want to show it in the body, then just copy the code from Builder and paste it in the body of the scaffold.
Scaffold(bottomNavigationBar: Builder(builder: (context) => Container(child: Row(children: <Widget>[
Icon(Icons.add_alarm), Icon(Icons.map), IconButton(icon: Icon(Icons.bookmark),
onPressed:() {
Scaffold.of(context).showSnackBar(mySnackBar);
final mySnackBar = SnackBar(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
behavior: SnackBarBehavior.floating,
backgroundColor: Colors.white, duration: Duration(seconds: 1),
content: Text(
'Article has been removed from bookmarks',
),);
}
),
],
),
),
),
);
Note: In the behaviour property of SnackBar, you can just leave it empty. But the problem with that is "If you have Curved Navigation Bar or you have a floating action button above the bottom navigation bar, then the snackbar will lift these icons (or FAB ) and will affect the UI". That's why SnackBar.floating is more preferred as it is more capatible with the UI.
But you can check and see on your own which suits you the best.

Showing selected image in alert dialog in flutter

How can i show the selected image in my alert dialog ?
In my app, i added an alert dialog which has the camera button. When user clicks the camera button, another alert dialog asks to select file from gallery. After the user selects image file from gallery, i want to show the image in the alert dialog with the camera button, but the image shows only after reopening the alert dialog.
I have posted my code below. I am new to flutter. Please can someone help me? Thanks in advance.
class Test extends StatefulWidget {
#override
_State createState() => new _State();
}
Future<File> imageFile;
class _State extends State<Test> {
Future<void> _openDailog() async {
return showDialog<void>(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return AlertDialog(
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0)),
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text('Click Photo'),
Ink(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24.0),
color: Colors.blue),
child: IconButton(
color: Colors.white,
icon: Icon(Icons.camera_alt),
onPressed: () {
_cameraOptions();
print("test");
},
),
)
],
),
content: SingleChildScrollView(
child: Container(
width: 300.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
showImage(),
InkWell(
child: Container(
margin: EdgeInsets.only(top: 8.0),
child: RaisedButton(
color: Colors.blue,
child: new Text(
"Send",
style: TextStyle(color: Colors.white),
),
onPressed: () {
Navigator.of(context).pop();
print("test");
},
),
)),
],
),
),
),
);
},
);
}
#override
Widget build(BuildContext context) {
// TODO: implement build
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FloatingActionButton(
heroTag: null,
child: Icon(Icons.insert_drive_file),
onPressed: () {
_openDailog();
},
)
],
);
}
Future<void> _cameraOptions() {
return showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
content: new SingleChildScrollView(
child: new ListBody(
children: <Widget>[
FlatButton(
onPressed: () {
pickImageFromGallery(ImageSource.gallery);
Navigator.of(context).pop();
},
color: Colors.transparent,
child: new Text(
'Select From Gallery',
textAlign: TextAlign.start,
style: new TextStyle(
decoration: TextDecoration.underline,
),
),
),
],
),
),
);
});
}
pickImageFromGallery(ImageSource source) {
setState(() {
imageFile = ImagePicker.pickImage(source: source);
});
}
Widget showImage() {
return FutureBuilder<File>(
future: imageFile,
builder: (BuildContext context, AsyncSnapshot<File> snapshot) {
if (snapshot.connectionState == ConnectionState.done &&
snapshot.data != null) {
return Image.file(
snapshot.data,
width: MediaQuery.of(context).size.width,
height: 100,
);
} else if (snapshot.error != null) {
return const Text(
'Error Picking Image',
textAlign: TextAlign.center,
);
} else {
return const Text(
'No Image Selected',
textAlign: TextAlign.center,
);
}
},
);
}
}
That is because you would need to setState() however you can't do that in an alert dialogue as it doesn't have its own state, the workaround for that would be to have the dialogue be its own stateful widget. Please check out this article as it shows how to do that. If you faced problems let me know!
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path_provider/path_provider.dart';
void main() {
runApp(new MaterialApp(
home: new MyHomePage(),
));
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _selectedIndex = 0;
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
title: Text("StackoverFlow"),
),
body: Container(),
floatingActionButton: FloatingActionButton(
onPressed: () async {
await _dialogCall(context);
},
),
);
}
Future<void> _dialogCall(BuildContext context) {
return showDialog(
context: context,
builder: (BuildContext context) {
return MyDialog();
});
}
}
class MyDialog extends StatefulWidget {
#override
_MyDialogState createState() => new _MyDialogState();
}
class _MyDialogState extends State<MyDialog> {
String imagePath;
Image image;
#override
Widget build(BuildContext context) {
return AlertDialog(
content: new SingleChildScrollView(
child: new ListBody(
children: <Widget>[
Container(child: image!= null? image:null),
GestureDetector(
child: Row(
children: <Widget>[
Icon(Icons.camera),
SizedBox(width: 5),
Text('Take a picture '),
],
),
onTap: () async {
await getImageFromCamera();
setState(() {
});
}),
Padding(
padding: EdgeInsets.all(8.0),
),
],
),
),
);
}
Future getImageFromCamera() async {
var x = await ImagePicker.pickImage(source: ImageSource.camera);
imagePath = x.path;
image = Image(image: FileImage(x));
}
}
Try this solution with GestureDetector() .it works
onTap:()async{
var image = await ImagePicker.pickImage(
source: ImageSource.gallery).whenComplete((){
setState(() {
});
}
);
setState(() {
_image = image;
});
},

Snackbar in SimpleDialog Flutter

I faced an error code below when adding a snackbar to an on-pressed method in my Simpledialog.
[Scaffold.of() called with a context that does not contain a Scaffold.]
I would like to seek your advice on how to provide the correct context to resolve it.
import 'package:flutter/material.dart';
void main() {
runApp(new MaterialApp(home: new AlertApp()));
}
class AlertApp extends StatefulWidget {
#override
_AlertAppState createState() => _AlertAppState();
}
class _AlertAppState extends State<AlertApp> {
SimpleDialog _simdalog;
void sDialog(){
_simdalog = new SimpleDialog(
title: new Text("Add To Shopping Cart"),
children: <Widget>[
new SimpleDialogOption(
child: new Text("Yes"),
onPressed: (){
final snackBar = SnackBar(content: Text('Purchase Successful'));
Scaffold.of(context).showSnackBar(snackBar);
},
),
new SimpleDialogOption(
child: new Text("Close"),
onPressed:() {Navigator.pop(context);},
),
],
);
showDialog(context: context, builder: (BuildContext context){
return _simdalog;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: new Center(
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new RaisedButton(
child: new Text("Add to Shopping Cart [Simple]"),
onPressed:(){
sDialog();
}),
],
),
),
);
}
}
Solution 1: as Mazin Ibrahim mentioned in comments Scaffold.of() called with a context that does not contain a Scaffold
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
...
Scaffold(
key: _scaffoldKey,
...
onPressed: () {
_scaffoldKey.currentState.showSnackBar(
SnackBar(
content: Text('Purchase Successful'),
duration: Duration(seconds: 3),
));
}
Solution 2:
With package flushbar, you can also display notification on top
Flushbar link : https://github.com/AndreHaueisen/flushbar
Another suggestion to use flushbar How to show snackbar after navigator.pop(context) in Flutter?
Flushbar(
title: "Hey Ninja",
message: "Lorem Ipsum is simply dummy text of the printing and typesetting industry",
flushbarPosition: FlushbarPosition.TOP,
flushbarStyle: FlushbarStyle.FLOATING,
reverseAnimationCurve: Curves.decelerate,
forwardAnimationCurve: Curves.elasticOut,
backgroundColor: Colors.red,
boxShadows: [BoxShadow(color: Colors.blue[800], offset: Offset(0.0, 2.0), blurRadius: 3.0)],
backgroundGradient: LinearGradient(colors: [Colors.blueGrey, Colors.black]),
isDismissible: false,
duration: Duration(seconds: 4),
icon: Icon(
Icons.check,
color: Colors.greenAccent,
),
mainButton: FlatButton(
onPressed: () {},
child: Text(
"CLAP",
style: TextStyle(color: Colors.amber),
),
),
showProgressIndicator: true,
progressIndicatorBackgroundColor: Colors.blueGrey,
titleText: Text(
"Hello Hero",
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 20.0, color: Colors.yellow[600], fontFamily: "ShadowsIntoLightTwo"),
),
messageText: Text(
"You killed that giant monster in the city. Congratulations!",
style: TextStyle(fontSize: 18.0, color: Colors.green, fontFamily: "ShadowsIntoLightTwo"),
),
)..show(context);
You can return a bool from the showDialog method and use that to determine whether to show the snackbar:
void main() {
runApp(MaterialApp(
home: AlertApp(),
));
}
class AlertApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
MyShoppingButton(),
],
),
),
);
}
}
// Separate out the button from _AlertAppState so that the call to
// showSnackBar comes from a different BuildContext
class MyShoppingButton extends StatelessWidget {
#override
Widget build(BuildContext context) {
return RaisedButton(
child: Text("Add to Shopping Cart [Simple]"),
// Use an async onPressed method so that we can wait for the
// result from the dialog before deciding whether to show the snackbar
onPressed: () async {
bool result = await showDialog<bool>(
context: context,
builder: (BuildContext context) {
return MyShoppingDialog();
},
);
// Check if result is null below as Flutter will throw Exception if
// tries determining whether to enter an if branch will a null boolean
if (result != null && result) {
final snackBar = SnackBar(content: Text('Purchase Successful'));
Scaffold.of(context).showSnackBar(snackBar);
}
},
);
}
}
class MyShoppingDialog extends StatelessWidget {
#override
Widget build(BuildContext context) {
return SimpleDialog(
title: Text("Add To Shopping Cart"),
children: <Widget>[
SimpleDialogOption(
child: Text("Yes"),
onPressed: () {
// Pop with a result of true so that MyShoppingButton
// knows to show snackbar. In any other case
// (including the user dismissing the dialog), MyShoppingButton
// null receive null, and so will not show the snackbar
Navigator.of(context).pop(true);
},
),
SimpleDialogOption(
child: Text("Close"),
onPressed: () {
Navigator.pop(context);
},
),
],
);
}
}
You should create a Scaffold widget inside of showDialog and a Builder widget as child of the Scaffold and pass context as parameter.
void sDialog({BuildContext context}){
_simdalog = new SimpleDialog(
title: new Text("Add To Shopping Cart"),
children: <Widget>[
new SimpleDialogOption(
child: new Text("Yes"),
onPressed: (){
final snackBar = SnackBar(content: Text('Purchase Successful'));
Scaffold.of(context).showSnackBar(snackBar);
},
),
new SimpleDialogOption(
child: new Text("Close"),
onPressed:() {Navigator.pop(context);},
),
],
);
showDialog(context: context, builder: (BuildContext context){
return GestureDetector(
onTap: (){Navigator.of(context).pop();},
child: Scaffold(
body: Builder(
builder: (context){
return _simdalog(context: context);
}
),
),);
});
}