flutterflutter-cupertino

Flutter: radio button not updating state in RadioListTile inside showCupertinoModalPopup


I use RadioListTile inside showCupertinoModalPopup

By clicking the unselected radio button in RadioListTile inside showCupertinoModalPopup is not updated like selected.

Code:

class MainScreen extends StatefulWidget {
  @override
  _MainScreen createState() => _MainScreen();
}

class _MainScreen extends State<MainScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('My App'),),
      floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.search),
        onPressed: () {
          _showDatePicker(context);   // OPEN CUPERTINO MODAL POPUP
        },
      ),
    );
  }

  // CUPERTINO MODAL POPUP
  void _showDatePicker(BuildContext context) {
    showCupertinoModalPopup(
      context: context,
      builder: (BuildContext context) {
        return CupertinoActionSheet(
          title: const Text('Pick a time'),
          actions: <Widget>[
              Material(
                child: Column(
                  // build RadioListTile
                  children: <Widget>[
                    _myRadioButton("Option 1", 0, (newValue) => setState(() => _groupValue = newValue!)),
                    _myRadioButton("Option 2", 1, (newValue) => setState(() => _groupValue = newValue!),),
                  ],
                ),
              ),
              Container(
                height: 150.0,
                child: CupertinoDatePicker(
                initialDateTime: DateTime.now(),
                use24hFormat: true,
                onDateTimeChanged: (DateTime newDateTime) {},
              ),
            ),
          ],
          cancelButton: CupertinoActionSheetAction(
            child: const Text('Cancel'),
            onPressed: () {
              Navigator.pop(context);
            },
          ),
        );
      },
    );
  }

  Widget _myRadioButton(String title, int value, Function(int?) onChanged) {
    return RadioListTile(
      value: value,
      groupValue: _groupValue,
      onChanged: onChanged,  
      title: Text(title),
    );
  }
}

I click to toggle, but nothing happens. How state radio button in CupertinoActionSheet after clicking?


Solution

  • You can use StatefulBuilder to update dialog ui.

      void _showDatePicker(BuildContext context) {
        showCupertinoModalPopup(
          context: context,
          builder: (BuildContext context) {
            return StatefulBuilder(
              builder: (context, setState) =>  //this , setState, you may like to rename it and also call state class setState to reflect the main ui
              CupertinoActionSheet(
                title: const Text('Pick a time'),
                actions: <Widget>[
                  Material(
                    child: Column(
                      // build RadioListTile
                      children: <Widget>[
                        _myRadioButton("Departure", 0,
                            (newValue) => setState(() => _groupValue = newValue!)),
                        _myRadioButton(
                          "Arrival",
                          1,
                          (newValue) => setState(() => _groupValue = newValue!),
                        ),
                      ],
                    ),
                  ),
                  Container(
                    height: 150.0,
                    child: CupertinoDatePicker(
                      initialDateTime: DateTime.now(),
                      use24hFormat: true,
                      onDateTimeChanged: (DateTime newDateTime) {},
                    ),
                  ),
                ],
                cancelButton: CupertinoActionSheetAction(
                  child: const Text('Cancel'),
                  onPressed: () {
                    Navigator.pop(context);
                  },
                ),
              ),
            );
          },
        );
      }