Flutter ReorderableList拖动时出现Multiple GlobalKey重复报错求解
问题原因
你遇到的重复GlobalKey报错是3个问题共同导致的:
- 任务列表初始化逻辑错误:你把
getList()方法放在build函数中执行,Flutter每次页面刷新都会触发build,每次都会往现有的taskList里新增10条id为0-9的任务,最终出现大量重复id的任务项,生成的Key自然重复。 - 子组件Key传值错误:你在构建
IntrayTodo组件时给keyValue传了空字符串,所有IntrayTodo的Container组件Key都是空值,全部重复。 - 重排序逻辑不完善:你在
ReorderableListView内直接写的onReorder逻辑没有处理新索引大于旧索引的偏移问题,会导致排序后索引计算错误,进一步加剧Key冲突。
修复步骤
- 把任务列表初始化移到initState中,避免每次build重复新增任务,同时修改getList方法避免列表累加:
class _IntrayPageState extends State<IntrayPage> { List<Task> taskList = []; // 新增initState生命周期方法 @override void initState() { super.initState(); taskList = getList(); } @override Widget build(BuildContext context) { // 删掉原来这里的taskList = getList(); return Container( color: darkGreyColor, child: _buildReorderableListSimple(context), ); } // 修改getList逻辑,每次返回新的列表,不往原有列表累加 List<Task> getList() { List<Task> newList = []; for (int i = 0; i < 10; i++) { newList.add(Task("My first todo " + i.toString(), false, i.toString())); } return newList; } }
- 修正IntrayTodo的keyValue传值,传入唯一的taskId,不要传空字符串:
Widget _buildListTile(BuildContext context, Task item) { return ListTile( key: Key(item.taskId), title: IntrayTodo( title: item.title, keyValue: item.taskId, // 替换空字符串为唯一的taskId ), ); }
- 替换成正确的重排序逻辑,直接调用你已经写好的
_onReorder方法即可:
Widget _buildReorderableListSimple(BuildContext context) { return Theme( data: ThemeData(canvasColor: Colors.transparent), child: ReorderableListView( padding: EdgeInsets.only(top: 200.0), children: taskList.map((Task item) => _buildListTile(context, item)).toList(), onReorder: _onReorder, // 直接调用已经做好索引兼容的处理方法 ), ); }
如果不需要用IntrayTodo的Key做其他逻辑,也可以直接删掉IntrayTodo组件里Container的key属性,进一步避免冲突。修复后重新运行即可解决重复Key的报错,重排序功能也能正常使用。
内容的提问来源于stack exchange,提问作者Abdi
相关产品推荐
相关产品推荐

