Flutter中如何实现选中列表项并添加至原列表上方的新列表?
解决选中元素添加到上方列表的问题
你当前的代码已经实现了记录选中项的ID,但没有把对应的完整数据项同步到chosenListsAbove列表中。可以按以下方式修改:
1. 修正选中/取消选中的逻辑
把选中回调里的逻辑改成同时维护multipleSelected和chosenListsAbove两个列表:
void _onCategorySelected(bool selected, Map<String, dynamic> item) { setState(() { if (selected) { multipleSelected.add(item['id']); chosenListsAbove.add(item); // 将完整数据项加入上方列表 } else { multipleSelected.remove(item['id']); chosenListsAbove.removeWhere((element) => element['id'] == item['id']); // 根据ID移除对应项 } }); }
2. 调整Checkbox的传参逻辑
在Checkbox的onChanged里传入完整的item对象,方便后续操作:
onChanged: (bool? selected) { _onCategorySelected(selected!, baseNames![i]); }
3. 处理空安全问题
在itemBuilder里先判断baseNames是否为空,避免空指针异常:
itemBuilder: (context, i) { if (baseNames == null) return SizedBox.shrink(); // 后续逻辑 }
4. 渲染上方的选中列表
在页面Widget树中加入chosenListsAbove的展示区域,比如放在原选择列表的上方:
Widget build(BuildContext context) { return Column( children: [ // 上方的选中标签列表 Container( height: 100, padding: EdgeInsets.symmetric(vertical: 10), child: ListView.builder( scrollDirection: Axis.horizontal, itemCount: chosenListsAbove.length, itemBuilder: (context, index) { final item = chosenListsAbove[index]; return Padding( padding: EdgeInsets.symmetric(horizontal: 8), child: Chip( label: Text(item['name'], style: TextStyle(color: Colors.white)), backgroundColor: Colors.green, onDeleted: () { setState(() { // 删除标签时同步更新两个列表 multipleSelected.remove(item['id']); chosenListsAbove.removeAt(index); }); }, ), ); }, ), ), // 原有的选择列表 Expanded(child: chosendataBase()), ], ); }
完整修改后的chosendataBase方法
Widget chosendataBase() { return FutureBuilder<List>( future: BasesService().GetBases(), builder: (context, snapshot) { List? baseNames = snapshot.data; // 处理加载状态 if (snapshot.connectionState == ConnectionState.waiting) { return Center(child: CircularProgressIndicator(color: Colors.green)); } if (snapshot.hasError) { return Center(child: Text('加载失败', style: TextStyle(color: Colors.white))); } return ListView.builder( shrinkWrap: true, itemCount: baseNames?.length ?? 0, itemBuilder: (context, i) { if (baseNames == null) return SizedBox.shrink(); final currentItem = baseNames[i]; void _onCategorySelected(bool selected) { setState(() { if (selected) { multipleSelected.add(currentItem['id']); chosenListsAbove.add(currentItem); } else { multipleSelected.remove(currentItem['id']); chosenListsAbove.removeWhere((item) => item['id'] == currentItem['id']); } }); } return ListTile( title: Padding( padding: const EdgeInsets.only(left: 1.0), child: Text( currentItem['name'] ?? '未加载', style: TextStyle( fontFamily: 'fonts/Montserrat', fontSize: 24, fontWeight: FontWeight.w900, color: Colors.white, ), ), ), leading: Checkbox( activeColor: Colors.green, checkColor: Colors.green, side: BorderSide(width: 2, color: Colors.white), value: multipleSelected.contains(currentItem['id']), onChanged: (bool? selected) { if (selected != null) _onCategorySelected(selected); }, ), ); }, ); }, ); }
修改后,选中列表项时对应的完整数据会被加入chosenListsAbove,取消选中时会从该列表移除,上方的标签列表也会实时同步更新。
内容的提问来源于stack exchange,提问作者user16357470
相关产品推荐
相关产品推荐

