Flutter中如何实现Radio单选框支持多选功能?
实现可多选的Radio风格选项
你当前用的Flutter原生Radio组件本身是单选逻辑,同一组只能选中一个选项。要实现多选,得调整状态管理和组件逻辑,以下是具体实现方案:
核心思路
用集合存储所有选中的选项ID,替换原来的单个选中ID变量;然后用支持多选的组件(或自定义Radio样式),点击时切换选项的选中状态。
具体实现步骤
1. 修改状态变量
把原来的id和radioButtonItem替换成一个集合,用来记录所有选中的选项ID:
// 初始化空集合,存储选中的选项ID(用Set避免重复选中同一选项) Set<int> selectedIds = {};
2. 替换组件并修改交互逻辑
原生Radio不支持多选,这里提供两种实用方案:
方案一:用Checkbox模拟Radio外观(快捷实现)
把Radio换成Checkbox,并设置圆形样式,保持和Radio近似的视觉效果:
Row( children: [ Expanded( flex: 2, child: Container( // 注意原代码里的Containers应为Container,若为自定义组件可保留 height: size.height, child: Checkbox( activeColor: Colors.white, checkColor: const Color.fromRGBO(44, 39, 36, 0.75), shape: const CircleBorder(), // 设置为圆形,模拟Radio样式 value: selectedIds.contains(_data[index].id), onChanged: (bool? isChecked) { setState(() { if (isChecked == true) { selectedIds.add(_data[index].id); } else { selectedIds.remove(_data[index].id); } }); }, ), ), ), Expanded( flex: 5, child: Container( height: size.height, child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ Texts( // 若为自定义文本组件可保留,原生组件替换为Text texts: _data[index].name, fontSize: 16.sp, fontWeight: FontWeight.w500, color: selectedIds.contains(_data[index].id) ? Colors.white : const Color.fromRGBO(44, 39, 36, 0.75), textAlign: TextAlign.left, ), ], ), ), ) ], ),
方案二:自定义Radio样式的多选按钮
如果需要完全一致的Radio视觉效果,可用InkWell包裹自定义圆形容器模拟:
Row( children: [ Expanded( flex: 2, child: Container( height: size.height, child: InkWell( onTap: () { setState(() { // 点击切换选中状态 if (selectedIds.contains(_data[index].id)) { selectedIds.remove(_data[index].id); } else { selectedIds.add(_data[index].id); } }); }, child: Container( width: 24, // 自定义Radio尺寸 height: 24, decoration: BoxDecoration( shape: BoxShape.circle, border: Border.all( color: selectedIds.contains(_data[index].id) ? Colors.white : const Color.fromRGBO(44, 39, 36, 0.75), width: 2, ), color: selectedIds.contains(_data[index].id) ? Colors.white : Colors.transparent, ), child: selectedIds.contains(_data[index].id) ? const Icon( Icons.check, size: 16, color: Color.fromRGBO(44, 39, 36, 0.75), ) : null, ), ), ), ), Expanded( flex: 5, child: Container( height: size.height, child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ Texts( texts: _data[index].name, fontSize: 16.sp, fontWeight: FontWeight.w500, color: selectedIds.contains(_data[index].id) ? Colors.white : const Color.fromRGBO(44, 39, 36, 0.75), textAlign: TextAlign.left, ), ], ), ), ) ], ),
3. 获取选中的选项
需要使用选中数据时,直接从selectedIds集合筛选即可:
// 从数据源中筛选出所有选中的选项 List<YourDataModel> selectedItems = _data.where((item) => selectedIds.contains(item.id)).toList();
内容的提问来源于stack exchange,提问作者Mr.Robot
相关产品推荐
相关产品推荐

