Home > database >  In flutter, how do I dynamically update an alert dialog's action list?
In flutter, how do I dynamically update an alert dialog's action list?

Time:12-09

I am trying to dynamically update an alert dialog's action list when something takes place in the alert dialog. Essentially, by default the dialog has a "Cancel" action button. But once the user does something in the dialog, I want it to have a "Cancel" and an "Accept" button. I have tried using a StatefulBuilder, which is how I am getting the rest of the dialog to update state. However, it is not working with the action buttons.

I've tried conditionally rendering the button, as well as generating a list to use for the dialog actions, and using setState to add to the list when an action takes place. Neither works, although other state updates within the dialog's content work with the StatefulBuilder. The dialog opens with only the "Cancel" action, and will not update to include the "Accept" action as well.

await showDialog<void>(
  context: context,
  builder: (BuildContext context) {
    int? selectedRadio = 0;
    return AlertDialog(
      content: StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return Column(
            mainAxisSize: MainAxisSize.min,
            children: List<Widget>.generate(4, (int index) {
              return Radio<int>(
                value: index,
                groupValue: selectedRadio,
                onChanged: (int? value) {
                  setState(() => selectedRadio = value);
                },
              );
            }),
            actions: <Widget>[
              TextButton(
                child: Text('Cancel'),
                onPressed: () {
                  Navigator.of(context).pop();
                },
              ),
              selectedRadio == 1 ? TextButton(
                child: Text('Accept'),
                onPressed: () {
                  Navigator.of(context).pop();
                },
              ) : SizedBox.Shrink(),
            ],
          );
        },
      ),
    );
  },
);

CodePudding user response:

Try putting the AlertDialog inside the StatefulBuilder

return StatefulBuilder(
      builder: (context, setState) {
        return AlertDialog(

CodePudding user response:

Create a StatefulWidget to display your AlertDialog, and manage selectedRadio there. Also take advantage of Dart's collection if to handle the conditional button:

class MyDialog extends StatefulWidget {
  const MyDialog({Key? key}) : super(key: key);
  @override
  State<MyDialog> createState() => _MyDialogState();
}

class _MyDialogState extends State<MyDialog> {
  int selectedRadio = 0;
  @override
  Widget build(BuildContext context) {
    return AlertDialog(
        actions: <Widget>[
          TextButton(
            child: Text('Cancel'),
            onPressed: () {
              Navigator.of(context).pop();
            },
          ),
          if (selectedRadio == 1)
            TextButton(
              child: Text('Accept'),
              onPressed: () {
                Navigator.of(context).pop();
              },
            )
        ],
        content: Column(
          mainAxisSize: MainAxisSize.min,
          children: List<Widget>.generate(4, (int index) {
            return Radio<int>(
              value: index,
              groupValue: selectedRadio,
              onChanged: (int? value) {
                setState(() => selectedRadio = value!);
              },
            );
          }),
        ));
  }
}

After this, you can display your dialog for example like this:

TextButton(
    child: Text('Pressme'),
    onPressed: () async => await showDialog<void>(
          context: context,
          builder: (BuildContext context) {
            return const MyDialog();
          },
        ))
  • Related