Flutter中如何按ID获取列表元素 修复Checkbox选中标签错显问题
问题根源
你出现标签串用的核心原因是所有日期条目共用了同一个全局标签列表_timingTagListForToken,没有给每个日期单独存储自己的标签数据,所以只要是勾选状态的日期,都会渲染同一个列表的内容,自然就出现了加一个标签所有选中日期都显示的问题。
另外还有两个逻辑漏洞:
- 弹窗提交逻辑没有将输入的时间和选中的日期绑定,只是清空了输入框
- 渲染标签时的下标和唯一键没有和对应日期绑定,容易出现渲染异常
修复方案
步骤1:修改日期模型类,新增单独存储标签的字段
给CheckBoxListTileModelForToken新增每个日期独有的标签列表字段,避免共用全局列表:
class CheckBoxListTileModelForToken { int id; String title; bool isCheck; List<String> timingTags; // 新增:存储当前日期对应的时间标签 CheckBoxListTileModelForToken({ required this.id, required this.title, required this.isCheck, List<String>? timingTags, }) : timingTags = timingTags ?? []; // 默认初始化为空列表 static List<CheckBoxListTileModelForToken> getUsers() { return <CheckBoxListTileModelForToken>[ CheckBoxListTileModelForToken(id:1,title: "Monday", isCheck: true), CheckBoxListTileModelForToken(id:2,title: "Tuesday", isCheck: false), CheckBoxListTileModelForToken(id:3,title: "Wednesday", isCheck: false), CheckBoxListTileModelForToken(id:4,title: "Thursday", isCheck: false), CheckBoxListTileModelForToken(id:5,title: "Friday", isCheck: false), CheckBoxListTileModelForToken(id:6,title: "Saturday", isCheck: false), CheckBoxListTileModelForToken(id:7,title: "Sunday", isCheck: false), ]; } }
原来的全局列表_timingTagListForToken可以直接删除,不再使用。
步骤2:修改标签渲染逻辑,绑定当前日期的专属标签
修改ListView.builder中标签部分的代码,避免下标冲突,只读取当前日期自己的标签:
// 找到原来的Tags组件部分,替换为如下代码 checkBoxListTileModelForToken[index].isCheck? Tags( itemCount: checkBoxListTileModelForToken[index].timingTags.length, // 读取当前日期自己的标签数量 itemBuilder: (int tagIndex){ // 修改变量名,避免和外层的日期下标index冲突 return ItemTags( key: Key("${checkBoxListTileModelForToken[index].id}_$tagIndex"), // 用日期ID+标签下标做唯一键,避免渲染混乱 activeColor:HexColor("#5344ed"), index: tagIndex, title: checkBoxListTileModelForToken[index].timingTags[tagIndex], // 读取当前日期自己的标签内容 textStyle: TextStyle( fontSize: 14, ), combine: ItemTagsCombine.withTextBefore, removeButton: ItemTagsRemoveButton( backgroundColor:HexColor("#5344ed"), onRemoved: (){ setState(() { // 删除当前日期对应下标的标签 checkBoxListTileModelForToken[index].timingTags.removeAt(tagIndex); }); return true; }, ), onPressed: (item) => print(item), onLongPressed: (item) => print(item), ); },):Padding( padding: const EdgeInsets.only(left: 70), child:Row(crossAxisAlignment: CrossAxisAlignment.center, children: []) )
步骤3:修改弹窗提交逻辑,把时间存储到对应日期的标签列表中
原来的提交逻辑只清空了输入框,没有存储数据,修改提交按钮的回调逻辑:
// 找到弹窗actions中的Submit按钮的onPressed回调,替换为如下代码 onPressed: () { // 非空校验,避免添加空标签 if (fromTimeForToken.text.isNotEmpty && toTimeForToken.text.isNotEmpty) { setState(() { // 根据传入的日期ID找到对应的条目 int targetDateIndex = checkBoxListTileModelForToken.indexWhere((item) => item.id == id); if (targetDateIndex != -1) { // 拼接时间标签,添加到对应日期的标签列表中 String timeTag = "${fromTimeForToken.text} - ${toTimeForToken.text}"; checkBoxListTileModelForToken[targetDateIndex].timingTags.add(timeTag); } // 清空输入框 fromTimeForToken.text = ""; toTimeForToken.text = ""; }); } Navigator.pop(context); },
完成以上修改后,每个日期都会单独存储自己的时间标签,不会再出现标签串用的问题。
内容的提问来源于stack exchange,提问作者TimeToCode
相关产品推荐
相关产品推荐

