Flutter点击按钮删除列表项后更新异常:删除后最后一项重复怎么解决?
问题根因及修复方案
核心问题1:渲染数据源与操作数据源不统一
你的逻辑存在明显的数据源不一致问题:
- 删除操作修改的是
historyList数组 - 但
ListView.builder的itemCount用的是snapshot.data.length,列表项渲染也取的是snapshot.data[index]的数据
snapshot.data是FutureBuilder首次拿到_getRecord()返回的原始接口数据,你修改historyList完全不会影响snapshot.data的值,所以列表长度始终是接口返回的原始长度,删除后空缺的位置会自动复用最后一项的数据,出现重复展示的问题。
核心问题2:FutureBuilder重复触发隐患
你没有给FutureBuilder指定固定的future参数实例,每次页面重绘都会重新调用_getRecord()拉取数据,如果你在_getRecord()里做了往historyList追加数据的逻辑,还会导致列表数据重复累加。
修复步骤
- 统一数据源,列表渲染完全使用
historyList,同时给列表项加唯一Key避免Diff算法识别错误
// 1. 先在State类里定义Future变量,避免FutureBuilder重复请求 late Future _recordFuture; @override void initState() { super.initState(); // 初始化时仅请求一次接口 _recordFuture = _getRecord(); } // 2. 调整FutureBuilder及ListView逻辑 Container( padding: EdgeInsets.fromLTRB(10, 70, 0, 0), child: FutureBuilder( future: _recordFuture, builder: (BuildContext context, AsyncSnapshot<List<leaveHistory>> snapshot) { if (snapshot.hasData) { if(historyList.isNotEmpty){ return Container( padding: EdgeInsets.fromLTRB(0, 30, 0, 0), child:Expanded( child: ListView.builder( // 统一使用historyList的长度 itemCount: historyList.length, scrollDirection: Axis.vertical, // 给每个列表项加唯一Key itemBuilder: (BuildContext context, int index) { // 渲染统一取historyList的数据,不要用snapshot.data final currentItem = historyList[index]; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text("Date: ${currentItem.date}",style: TextStyle(fontSize: 15),), FlatButton( child: Text("Approved",), onPressed: (){ _deleteItem(index); }, ) ], ); } ) ) ); } // 空列表占位逻辑可自行补充 return SizedBox.shrink(); } // 加载中占位逻辑可自行补充 return CircularProgressIndicator(); } ) )
- 调整
_getRecord()逻辑,接口返回数据后直接赋值给historyList,不要做追加操作:
Future _getRecord() async { // 此处替换为你实际的接口请求逻辑 final apiResponse = await requestLeaveHistoryApi(); // 直接全量赋值,不要用add/addAll做增量追加 historyList = apiResponse.map((item) => leaveHistory.fromJson(item)).toList(); return historyList; }
内容的提问来源于stack exchange,提问作者TimeToCode
相关产品推荐
相关产品推荐

