I’m working on a Flutter project where I have a column widget containing a list of ElevatedButtons generated dynamically based on an API response. When a button is pressed, display an AlertDialog. During the time the button was pressed to the AlertDialog is open, I’d like to disable all the buttons in the column to prevent users from interacting with them until the dialog is closed. How can I achieve this functionality?
FutureBuilder<Map<String, dynamic>>(
future: _apiService.fetchData(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator());
}
if (snapshot.hasError || !snapshot.hasData) {
return Center(child: Text('Error: ${snapshot.error ?? "No data"}'));
}
final String companyName = snapshot.data!['company']?.name ?? '';
final List<dynamic> categoriesData = snapshot.data!['categories'] ?? [];
return Column(
children: categoriesData.map<Widget>((category) {
final String nameEn = category.nameEn;
final String nameBn = category.nameBn;
bool isProcessing = false;
bool isButtonEnabled = true;
return StatefulBuilder(
builder: (context, setState) {
final bool isSelected = isLoadingIndex == categoriesData.indexOf(category);
return Column(
children: [
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Theme.of(context).colorScheme.primary,
fixedSize: Size(screenWidth * 0.8, screenHeight * 0.1),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5),
),
),
onPressed: isButtonEnabled ? () async {
setState(() {
isLoadingIndex = categoriesData.indexOf(category);
isButtonEnabled = false;
isProcessing = true;
isButtonPressed = true;
});
final int categoryID = category.id;
final url = URL;
final response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
final responseData = json.decode(response.body);
print(responseData);
final data = responseData['data'];
final Token = data['token'];
final Time = data['time'];
print('Token: $Token, Time and Date: $Time');
final SunmiPosSdk sunmiPosSdk = SunmiPosSdk();
await sunmiPosSdk.printReceipt(context, '$Token', '$Time', '$nameEn', '$nameBn', '$companyName');
showDialog(
context: context,
builder: (BuildContext context) {
barrierColor: Colors.grey.withOpacity(0.5);
barrierDismissible: false;
return Center(
child: buildAlertDialog(Token, Time, '$nameEn ($nameBn)'),
);
},
);
} else {
print('Failed to fetch data: ${response.statusCode}');
}
setState(() {
isLoadingIndex = -1;
isButtonEnabled = true;
isProcessing = false;
isButtonPressed = false;
});
}: null,
child: FittedBox(
fit: BoxFit.scaleDown,
child: Text(
'$nameEn ($nameBn)',
style: const TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
),
),
if (isProcessing)
GestureDetector(
onTap: () {},
child: Container(
color: Colors.transparent,
),
),
SizedBox(height: screenHeight * 0.01),
],
);
},
);
}).toList(),
);
},
),
2
Answers
you can create a check
isDailogBoxOpen
when opening the dialog box set the value of the check to true, and in buttons use this check to make them disable.You are passing the barrierDismissible inside builder: that’s why it is dismissing.
Pass it inside showDialog like this.
Now your Dialog will not close without the Button press(Manual Closing).