Flutter实现单选自定义按钮:航班选舱功能开发求助
当前代码的问题点
- 所有按钮文本重复为
Economy,未区分不同舱位(如经济舱、超级经济舱、商务舱) - 第一个按钮额外嵌套
Container添加边框,与ToggleButtons自带边框重复,导致样式混乱 - 缺少
onPressed回调,点击按钮无法更新选中状态 - 字体大小不一致,UI视觉不协调
正确实现方案
ToggleButtons完全适配舱位单选场景,只需补充状态更新逻辑并统一样式:
- 实现单选逻辑:在
onPressed回调中,点击对应索引时仅将该位置设为true,其余设为false,确保同一时间仅选中一个舱位 - 统一文本与样式:修改按钮文本为实际舱位名称,移除多余的Container边框,统一字体大小,利用ToggleButtons自身属性控制选中/未选中状态
- 优化UI细节:添加圆角、调整内边距,设置选中/未选中时的文本颜色,提升视觉体验
修正后的完整代码
import 'package:flutter/material.dart'; class CabinClassSelector extends StatefulWidget { const CabinClassSelector({Key? key}) : super(key: key); @override State<CabinClassSelector> createState() => _CabinClassSelectorState(); } class _CabinClassSelectorState extends State<CabinClassSelector> { // 初始选中经济舱 List<bool> isSelected = [true, false, false]; // 舱位名称列表 final List<String> cabinClasses = ["Economy", "Premium", "Business"]; @override Widget build(BuildContext context) { return ToggleButtons( // 选中时的填充色 fillColor: Theme.of(context).primaryColor, // 未选中时的边框色 borderColor: Theme.of(context).primaryColor, // 选中时的边框色 selectedBorderColor: Theme.of(context).primaryColor, // 边框圆角 borderRadius: BorderRadius.circular(8), // 内边距 padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12), // 选中状态列表 isSelected: isSelected, // 点击回调:实现单选逻辑 onPressed: (int index) { setState(() { // 遍历所有选项,仅将当前点击的设为true for (int i = 0; i < isSelected.length; i++) { isSelected[i] = i == index; } }); // 可在此添加选中后的回调,比如将选中舱位传递给父组件 // 示例:widget.onCabinSelected(cabinClasses[index]); }, // 动态生成按钮子项 children: cabinClasses .map((className) => Text( className, style: TextStyle( fontWeight: FontWeight.w500, fontSize: 16, // 选中时文本为白色,未选中时为主题色 color: isSelected[cabinClasses.indexOf(className)] ? Colors.white : Theme.of(context).primaryColor, ), )) .toList(), ); } }
关键说明
- 单选逻辑:通过遍历
isSelected列表,仅标记点击索引为选中状态,保证舱位单选的交互逻辑 - 样式控制:利用ToggleButtons内置属性替代额外Container,避免样式冲突,同时简化代码结构
- 可扩展性:舱位名称抽离为列表,后续新增舱位只需修改
cabinClasses,无需调整UI代码 - 交互反馈:点击触发
setState更新状态,UI自动刷新选中样式,提供清晰的交互反馈
内容的提问来源于stack exchange,提问作者Faheem John
相关产品推荐
相关产品推荐

