Reputation: 169
In my code, there is a condition that pops up the following dialog:
Its code looks like this:
//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;
},
);
}
I need my user to not be able to tap on the screen or press the back button. Only two buttons need to be active (Answer 1.1 and Answer 1.2 in this example).
How to do it? Thanks in advance.
Edit1. I don't know what I'm doing wrong. Here is my code where I followed your advice:
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
await showDialog;
// await showDialog or Show add banners or whatever
// return true if the route to be popped
return false; // return false if you want to disable device back button click
},
child: Scaffold(
appBar: AppBar(
title: const Text('New Game'),
),
body: Container(
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(assetPath),
fit: BoxFit.cover)),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Visibility(
child: Column(
children: [
ClipRRect(
borderRadius: BorderRadius.circular(4),
child: Stack(
children: <Widget>[
Positioned.fill(
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('files/sheet.jpg'),
fit: BoxFit.cover)),
),
),
Text(_listData[_listCount][0]),
],
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
ImageButton(label: 'OK', onButtonTap: _nextCSV),
ImageButton(label: 'Hide', onButtonTap: _isVisible),
ImageButton(label: 'Test1', onButtonTap: _showAlertDialog),
],
),
],
),
visible: isVisible,
),
// your other widgets
Visibility(
child: ImageButton(label: 'Show', onButtonTap: _isVisible),
visible: !isVisible,
)
],
),
),
),
);
}
But nothing has changed. I believe that I made a mistake here:
await showDialog;
However, when I do like this, nothing changes either. The back button still works:
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
return false; // return false if you want to disable device back button click
},
child: Scaffold(
...
As a result, I can still click on the back button. Although I want it to be inactive on the dialog. How to fix it?
Upvotes: 0
Views: 811
Reputation: 1472
You should wrap the AlertDialog with OnWillPop, not the Scaffold, since you need to set the action pop for the AlertDialog widget.
Here's a minimal example of how to implement the OnWillPop widget to match your case:
class MyHomePage extends StatefulWidget {
final String title;
const MyHomePage({
Key? key,
required this.title,
}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: ElevatedButton(
onPressed: () {
_showAlertDialog();
},
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.blue),
),
child: const Text(
"Open Dialog",
style: TextStyle(color: Colors.white),
))),
);
}
void _showAlertDialog() {
// set up the buttons
Widget Answer1Button = TextButton(
child: Text("Button 1"),
onPressed: () {
Navigator.pop(context);
},
);
Widget Answer2Button = TextButton(
child: Text("Button 2"),
onPressed: () {
Navigator.pop(context);
},
);
// set up the AlertDialog
AlertDialog alert = AlertDialog(
// title: Text(),
content: Text("Alert Dialog"),
actions: [
Answer1Button,
Answer2Button,
],
);
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return WillPopScope(
onWillPop: () async {
return false;
},
child: alert);
},
);
}
}
Upvotes: 1
Reputation: 1388
There is one parameter called barrierDismissible
which you can use to dismiss any tap of background of dialog,
showDialog(
barrierDismissible: false,
)
You can disable back button by wrapping the scaffold with WillPopScope.
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
// await showDialog or Show add banners or whatever
// return true if the route to be popped
return false; // return false if you want to disable device back button click
},
child: Scaffold(),
),
};
Here is the docs links https://api.flutter.dev/flutter/widgets/WillPopScope-class.html
Upvotes: 0
Reputation: 202
You can pass a parameter named 'barrierDismissible' in the showDialog, set it to false.
showDialog(
barrierDismissible: false,
builder: ...
)
Upvotes: 0