You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter:showCupertinoModalPopup内RadioListTile状态不更新

解决CupertinoActionSheet内RadioListTile无法切换选中状态的问题

问题核心:你调用的setState属于主页面的_MainScreen状态,而CupertinoActionSheet是独立的弹窗组件,主页面的setState只会刷新主页面UI,无法触发弹窗内部的UI更新,导致单选按钮状态变化后不显示选中效果。

下面提供两种可行的解决方案:

方案一:使用StatefulBuilder局部管理弹窗状态

在弹窗内部的单选按钮区域用StatefulBuilder包裹,它会提供一个局部的setState方法,仅刷新该区域的UI:

首先在_MainScreen类中添加状态变量:

class _MainScreen extends State<MainScreen> {
  int _groupValue = 0; // 定义单选组状态变量
  // ... 其他原有代码
}

然后修改_showDatePicker方法中的弹窗构建部分:

void _showDatePicker(BuildContext context) {
  showCupertinoModalPopup(
    context: context,
    builder: (BuildContext context) {
      return CupertinoActionSheet(
        title: const Text('Pick a time'),
        actions: <Widget>[
          // 用StatefulBuilder包裹单选按钮区域
          StatefulBuilder(
            builder: (context, popupSetState) {
              return Material(
                child: Column(
                  children: <Widget>[
                    _myRadioButton(
                      "Option 1", 
                      0, 
                      (newValue) => popupSetState(() => _groupValue = newValue!)
                    ),
                    _myRadioButton(
                      "Option 2", 
                      1, 
                      (newValue) => popupSetState(() => _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);
          },
        ),
      );
    },
  );
}

调用StatefulBuilder提供的popupSetState方法,就能实时刷新弹窗内的RadioListTile选中状态。

方案二:将弹窗单选区域抽为独立StatefulWidget

把单选按钮部分封装成独立的状态组件,让它自己管理内部状态,同时通过回调同步主页面的状态:

1. 创建独立的单选组件

class RadioOptionsWidget extends StatefulWidget {
  final int initialValue;
  final void Function(int) onValueChanged;

  const RadioOptionsWidget({
    Key? key,
    required this.initialValue,
    required this.onValueChanged,
  }) : super(key: key);

  @override
  State<RadioOptionsWidget> createState() => _RadioOptionsWidgetState();
}

class _RadioOptionsWidgetState extends State<RadioOptionsWidget> {
  late int _groupValue;

  @override
  void initState() {
    super.initState();
    _groupValue = widget.initialValue;
  }

  Widget _buildRadioTile(String title, int value) {
    return RadioListTile(
      value: value,
      groupValue: _groupValue,
      onChanged: (newValue) {
        setState(() {
          _groupValue = newValue!;
        });
        widget.onValueChanged(newValue!);
      },
      title: Text(title),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Material(
      child: Column(
        children: <Widget>[
          _buildRadioTile("Option 1", 0),
          _buildRadioTile("Option 2", 1),
        ],
      ),
    );
  }
}

2. 在主页面弹窗中使用该组件

void _showDatePicker(BuildContext context) {
  showCupertinoModalPopup(
    context: context,
    builder: (BuildContext context) {
      return CupertinoActionSheet(
        title: const Text('Pick a time'),
        actions: <Widget>[
          RadioOptionsWidget(
            initialValue: _groupValue,
            onValueChanged: (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);
          },
        ),
      );
    },
  );
}

这种方式更利于代码复用和状态隔离,适合复杂的弹窗内容。

内容的提问来源于stack exchange,提问作者Yury Matatov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 14:47:22