When I add a CheckBox() widget inside the content of the AlertDialog widget inside of the showDialog() function in the TextButton widget onPressed() function, I found that the checkbox did not rebuild when I click on it.
The checkbox did not rebuild because the showDialog() has its own build context. Even when I am using the StatefulWidget, the checkbox did not response and rebuild as expected when I click on it.
So, I wrap the AlertDialog widget using a StatefulBuilder widget and move the Boolean variable for the checkbox value above it and it solved the checkbox issue.
Here are the steps:
Before
import 'package:flutter/material.dart'; import '../../constants/colors.dart'; import '../../constants/styles.dart'; class DialogSendFeedback extends StatefulWidget { const DialogSendFeedback({super.key}); @override State<DialogSendFeedback> createState() => _DialogSendFeedbackState(); } class _DialogSendFeedbackState extends State<DialogSendFeedback> { final TextEditingController feedback = TextEditingController(); final FocusNode feedbackFocus = FocusNode(); bool agree = false; @override void dispose() { feedback.dispose(); feedbackFocus.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return TextButton.icon( onPressed: () { showDialog( context: context, builder: (context) { return AlertDialog( title: const Text('Send the project to Engineers'), content: SizedBox( width: 600, child: Column( mainAxisSize: MainAxisSize.min, children: [ const Row( children: [ Expanded( child: Text( 'We are sorry that you encountered some issues. To assist us in investigating the matter, kindly provide the details of the project.', maxLines: 3, )) ], ), const SizedBox( height: 16, ), Expanded( child: Row( children: [ Expanded( child: TextFormField( controller: feedback, focusNode: feedbackFocus, autofocus: true, keyboardType: TextInputType.multiline, textInputAction: TextInputAction.newline, maxLines: 100, decoration: const InputDecoration( alignLabelWithHint: true, contentPadding: EdgeInsets.all(8), label: Text('Issue detail'), hintText: 'Describe the issue as detailed as possible.'), )) ], ), ), const SizedBox( height: 16, ), Row( children: [ Checkbox( checkColor: whiteColor, fillColor: WidgetStateProperty.resolveWith( (states) => darkTealColor), value: agree, onChanged: (bool? value) { setState(() { agree = value!; }); }), const SizedBox( width: 8, ), const Expanded( child: Text( 'I agree to send these project details to Schletter Engineering for their investigation.', maxLines: 3, ), ) ], ) ], ), ), actions: [ TextButton( style: defaultPrimaryButtonStyle, onPressed: () { Navigator.of(context).pop(false); }, child: const Text( 'Do not send', style: buttonTextWhite, )), TextButton( style: defaultSecondaryButtonStyle, onPressed: agree == true ? () { Navigator.of(context).pop(true); } : null, child: Text( 'Send', style: defaultSecondaryButtonTextStyle, )) ], ); }, ).then((value) { if (value == true) { // make a call to backend API to save the feedback } }); }, icon: const Icon( Icons.help_outline_rounded, color: whiteColor, ), label: Text( 'Ask for help', style: defaultPrimaryButtonTextStyle, )); } } After
import 'package:flutter/material.dart'; import '../../constants/colors.dart'; import '../../constants/styles.dart'; class DialogSendFeedback extends StatefulWidget { const DialogSendFeedback({super.key}); @override State<DialogSendFeedback> createState() => _DialogSendFeedbackState(); } class _DialogSendFeedbackState extends State<DialogSendFeedback> { final TextEditingController feedback = TextEditingController(); final FocusNode feedbackFocus = FocusNode(); @override void dispose() { feedback.dispose(); feedbackFocus.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return TextButton.icon( onPressed: () { showDialog( context: context, builder: (context) { bool agree = false; // <- here return StatefulBuilder( // <- here builder: (context, setState) => AlertDialog( title: const Text('Send the project to Engineers'), content: SizedBox( width: 600, child: Column( mainAxisSize: MainAxisSize.min, children: [ const Row( children: [ Expanded( child: Text( 'We are sorry that you encountered some issues. To assist us in investigating the matter, kindly provide the details of the project.', maxLines: 3, )) ], ), const SizedBox( height: 16, ), Expanded( child: Row( children: [ Expanded( child: TextFormField( controller: feedback, focusNode: feedbackFocus, autofocus: true, keyboardType: TextInputType.multiline, textInputAction: TextInputAction.newline, maxLines: 100, decoration: const InputDecoration( alignLabelWithHint: true, contentPadding: EdgeInsets.all(8), label: Text('Issue detail'), hintText: 'Describe the issue as detailed as possible.'), )) ], ), ), const SizedBox( height: 16, ), Row( children: [ Checkbox( checkColor: whiteColor, fillColor: WidgetStateProperty.resolveWith( (states) => darkTealColor), value: agree, onChanged: (bool? value) { setState(() { agree = value!; }); }), const SizedBox( width: 8, ), const Expanded( child: Text( 'I agree to send these project details to Schletter Engineering for their investigation.', maxLines: 3, ), ) ], ) ], ), ), actions: [ TextButton( style: defaultPrimaryButtonStyle, onPressed: () { Navigator.of(context).pop(false); }, child: const Text( 'Do not send', style: buttonTextWhite, )), TextButton( style: defaultSecondaryButtonStyle, onPressed: agree == true ? () { Navigator.of(context).pop(true); } : null, child: Text( 'Send', style: defaultSecondaryButtonTextStyle, )) ], ), ); }, ).then((value) { if (value == true) { // make a call to backend API to save the feedback } }); }, icon: const Icon( Icons.help_outline_rounded, color: whiteColor, ), label: Text( 'Ask for help', style: defaultPrimaryButtonTextStyle, )); } } That’s it. Hopefully you found this post useful. Happy coding!
Top comments (0)