Flutter如何基于字符串数组实现互斥的RadioListTile单选组
你遇到的单选按钮无法互斥的核心原因是同组RadioListTile没有共用同一个groupValue状态变量:如果你的id变量是定义在每个单选按钮组件内部的,那么每个按钮的groupValue都是独立存储的,自然不会互相影响,就会出现可以同时选中多个的情况。

具体修复步骤
- 状态提升到父组件:将存储选中值的变量定义在生成所有单选按钮的父组件中,保证所有同组单选按钮共享同一个选中状态
- 同步组件参数:所有同组RadioListTile的
groupValue都绑定这个共享状态,选中回调中直接修改这个共享状态即可
完整示例代码
// 父组件中定义共享状态 int? _selectedId; // 所有同组单选按钮共用的groupValue final List<String> sample = ["选项1", "选项2", "选项3", "选项4"]; @override Widget build(BuildContext context) { return ListView.builder( itemCount: sample.length, itemBuilder: (context, index) { return buildRadioItem(index); }, ); } // 封装的单选按钮项组件 Widget buildRadioItem(int index) { return InkWell( onTap: () { // 同步InkWell点击事件的状态更新 setState(() { _selectedId = index; }); }, child: Container( child: Row( children: <Widget>[ Expanded( child: Container( height: 60.0, child: Theme( data: Theme.of(context).copyWith( unselectedWidgetColor: Colors.grey, disabledColor: Colors.blue), child: RadioListTile( title: Text("${sample[index]}", style: TextStyle(color: Colors.black)), groupValue: _selectedId, // 绑定父组件共享的选中状态 value: index, activeColor: Colors.green, onChanged: (val) { setState(() { _selectedId = val as int?; debugPrint('val answer$val'); }); }, // 不需要支持取消选中可删除以下配置 toggleable: true, ), )), ), ], ), ), ); }
注意事项
- 如果你给外层InkWell加了onTap回调,必须在回调里同步更新共享的选中状态,否则点击单选按钮的文字区域不会触发状态变更
- 如果不需要支持点击已选中按钮取消选中,删除
toggleable: true配置即可,默认单选按钮不允许取消选中 - 同组所有RadioListTile必须绑定同一个
groupValue,这是实现互斥效果的核心要求,只要这个配置正确,框架会自动处理选中互斥逻辑
内容的提问来源于stack exchange,提问作者user16991217
相关产品推荐
相关产品推荐

