alert dialog button not working when created with generic dialog flutter - flutter

enter image description here
i have created a generic dialog that can create buttons that return some values
import 'package:flutter/material.dart';
typedef DialogOptionBuilder<T> = Map<String, T?> Function();
Future<T?> showGenericDialog<T>({
required BuildContext context,
required String title,
required String content,
required DialogOptionBuilder optionBuilder,
}) {
final options = optionBuilder();
return showDialog<T>(
context: context,
builder: (context) {
return AlertDialog(
title: Text(title),
content: Text(content),
actions: options.keys.map((optionTitle) {
final value = options[optionTitle];
return TextButton(
onPressed: () {
if (value) {
Navigator.of(context).pop(value);
} else {
Navigator.of(context).pop();
}
},
child: Text(optionTitle),
);
}).toList(),
);
},
);
}
and when i try to use this generic dialog to create a simple alert dialog that has a button "ok" this "ok" button is not poping out the alert dialog even though i have coded to popout the dialog when no value is returned from the dialog when a button is pressed
Future<void> showCannotShareEmptyNoteDialog(BuildContext context) async {
return showGenericDialog<void>(
context: context,
title: 'Sharing',
content: "You can't share a empty note",
optionBuilder: () => {
'OK': null,
},
);
}
in here i'm calling the alert dialog
appBar: AppBar(
title: const Text("New Note"),
actions: [
IconButton(
onPressed: () async {
final text = _textController.text;
if (_note == null || text.isEmpty) {
await showCannotShareEmptyNoteDialog(context);
} else {
Share.share(text);
}
},
icon: const Icon(Icons.share),
),
],
),

ok button is not removing the alert dialog from the screen
thats because your condition below throw exception. since your type is void no value returned.
...
return TextButton(
onPressed: () {
if (value) { // this one is caused the error. because its null. not bool
Navigator.of(context).pop(value);
} else {
Navigator.of(context).pop();
}
error:
════════ Exception caught by gesture ═════════
type 'Null' is not a subtype of type 'bool'
change to this:
return TextButton(
onPressed: () {
if (value == true) {
Navigator.of(context).pop(value);
} else {
print(value);
Navigator.of(context).pop();
}
},

Related

How to check Alert Dialog is open only one times instead of multiple new dialog box after onTap in flutter

I am working on my flutter application and I want to check whether the alert dialog is open or not on the screen . Can anyone tell me how to do that, now everytime i press ontap and it will appear a new dialog box. how can i only appear one dialog box instead of multiple of new dialog box ?
I have try bool, ontap cancel all not working.
Future? _dialog;
Future<void> _checkTimer() async {
if (_dialog == null) {
_dialog = await Future.delayed(Duration(seconds: 5));
showTimer(context);
await _dialog;
_dialog = null;
} else {
//do nothing
}
}
showTimer(BuildContext context) {
// set up the buttons
// ignore: deprecated_member_use
if (didUserTouchedScreen = true){
Container alert = Container(child: _imageslideshowProductDetailstimer());
// show the dialog
showDialog(
barrierDismissible: true,
context: context,
builder: (BuildContext context) {
return WillPopScope(
onWillPop: () async {
didUserTouchedScreen = false;
// _checkTimer();
return true;
},
child: alert);
},
).then((_) => didUserTouchedScreen = false);
}}
behavior: HitTestBehavior.translucent,
onTapDown: (tapdown) {
print("down");
_checkTimer();
},
onTapCancel: (){print('up');_checkTimer();}
You can achieve this with a boolean state, let's call it isButtonActive. The button is enabled/disabled depending on the value of this state. When the button is pressed, set the state to false, and when the dialog box is closed, set the state to true.
Below is an example code:
class _HomePageState extends State<HomePage> {
bool isButtonActive = true;
showTimer(BuildContext context) async {
setState(() {
isButtonActive = false;
});
await Future.delayed(Duration(seconds: 2));
showDialog(
context: context,
builder: (BuildContext context) {
return Column(
children: const [
Text('qwerty'),
],
);
},
).then((value) {
setState(() {
isButtonActive = true;
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('총톤수'),
),
body: Center(
child: ElevatedButton(
onPressed: isButtonActive ? () => showTimer(context) : null,
child: const Text('총톤수'),
),
),
);
}
}

How to execute a function when a condition is met in Flutter/Dart?

I have a function:
//Alert Dialog about questions and answers
void _showAlertDialog() {
// set up the buttons
Widget Answer1Button = TextButton(
child: Text(_listData[_listCount][3]),
onPressed: () {},
);
Widget Answer2Button = TextButton(
child: Text(_listData[_listCount][4]),
onPressed: () {},
);
// set up the AlertDialog
AlertDialog alert = AlertDialog(
// title: Text(),
content: Text(_listData[_listCount][2]),
actions: [
Answer1Button,
Answer2Button,
],
);
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
It works great when I click on the button in the different place for testing. But how to make it run under the following condition:
void _nextCSV() {
setState(() {
_listData = _listData;
_listData[_listCount][2] == "" ? _showAlertDialog : print('False');
});
}
Thanks in advance.
You are missing the ()
void _nextCSV() {
setState(() {
_listData = _listData;
_listData[_listCount][2] == "" ? _showAlertDialog() : print('False');
});
}
But even inside the setState you can use if in case you want to.
Edited:
In case you want to ignore the then or the else block you could just put null.
condition ? null : result;
condition ? result : null;

wait until showdialog is closed flutter

I am trying to get the location permissions and I want to display a message before requesting the permission. but when I run the APP it doesn't wait until I close the showdialog
Future<void> checkPermission() async {
var status = await Permission.location.status;
print(status.toString());
if (status.isUndetermined) {
await showAlertPopup(context, '',
'OK')
.then((val) {
var statuses = Permission.location.request();
print(statuses);
});
}
if (status.isDenied ||
status.isPermanentlyDenied ||
status.isRestricted ||
status.isUndetermined) {
await showAlertPopup(context, '',
'error')
.then((val) {
openAppSettings();
});
}
if (status.isGranted) {
_geoAlowed = true;
}
}
and this is my code to display the popup
showAlertPopup(BuildContext context, String title, String detail) async {
showDemoDialog({BuildContext context, Widget child}) async {
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return child;
});
}
return showDemoDialog(
context: context,
child: AlertDialog(
title: Text(title),
content: Text(detail),
backgroundColor: grayLight,
actions: [
FlatButton(
child: Text('OK'),
onPressed: () {
Navigator.pop(context, 'OK');
},
),
],
),
);
}
As per your question, you want to request permission when user clicks 'OK' button in dialog.
You can create a callback, that is when user clicks 'OK'
showAlertPopup(context, '','OK', (){
//Code you want to execute when user clicks 'OK'
});
And little changes in you showAlertPopup
showAlertPopup(BuildContext context, String title, String detail, Function onClick) async {
showDemoDialog({BuildContext context, Widget child}) async {
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return child;
});
}
return showDemoDialog(
context: context,
child: AlertDialog(
title: Text(title),
content: Text(detail),
backgroundColor: grayLight,
actions: [
FlatButton(
child: Text('OK'),
onPressed: () {
//Your callback
onClick();
Navigator.pop(context, 'OK');
},
),
],
),
);
}

Flutter Modular Mobx - Observable doesn't update inside of onpress

I am new with Flutter and I am having a problem. I'm using mobx. In my view I have a button and inside of this button, I am waiting for the showDialog property to change in order to show the dialog view . However, within onpress the showdialog does not work. Is there any other way to do this?
My controller
#observable
bool showDialog = false;
#action
Future callLoginService() async {
await Future.delayed(Duration(seconds: 6));
showDialog = true;
}
view
Observer(
builder: (_) {
return Center(
child: RaisedButton(
child: Text("TESTE"),
onPressed: () async {
controller.callLoginService();
if (controller.showDialog) {
final action = await InfoDialogView.showAlertDialog(
context, "Try again", 'Invalid user');
if (action == DialogAction.abort) {
controller.showDialog = false;
}
}
},
),
);
},
),
This is because your onPressed method is asynchronous but you haven't used 'await' keyword ahead of controller.callLoginService().
Observer(
builder: (_) {
return Center(
child: RaisedButton(
child: Text("TESTE"),
onPressed: () async {
await controller.callLoginService(); //put await for calling asynchronous methods
if (controller.showDialog) {
final action = await InfoDialogView.showAlertDialog(
context, "Try again", 'Invalid user');
if (action == DialogAction.abort) {
controller.showDialog = false;
}
}
},
),
);
},
),

close Simple Dialog in flutter when setState needs to called

I'm having a problem calling Navigator.of(context).pop() on my onPressed property in SimpleDialogOption widget. I need to set the state and dismiss the dialog. But calling setState is preventing my dialog to close. Without setState the dialog closes. Here is my dialog
WidgetsBinding.instance.addPostFrameCallback((_) {
showDialog(
builder: (BuildContext context) {
return SimpleDialog(
children: _children(suburbs),
backgroundColor: Colors.white,
title: Text('Pick your suburb'),
);
},
context: context);
});
and the method I use for the list of the Dialog:
List<Widget> _children(List<Suburb> suburbs) {
return suburbs
.map((suburb) => SimpleDialogOption(
onPressed: () {
print('#####################');
setState(() {
postcode = suburb.name;
});
Navigator.of(context).pop();
},
child: Text(suburb.name)))
.toList();
}
you can await until the return value comes from the navigator.pop,
and then call a setState
WidgetsBinding.instance.addPostFrameCallback((_) async {
postcode = await showDialog(
builder: (BuildContext context) {
return SimpleDialog(
children: _children(suburbs),
backgroundColor: Colors.white,
title: Text('Pick your suburb'),
);
},
context: context);
setState(() {
postcode;
});
});
List<Widget> _children(List<Suburb> suburbs) {
return suburbs
.map((suburb) => SimpleDialogOption(
onPressed: () {
print('#####################');
Navigator.of(context).pop(suburb.name);
},
child: Text(suburb.name)))
.toList();
}