You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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追加数据的逻辑,还会导致列表数据重复累加。

修复步骤

  1. 统一数据源,列表渲染完全使用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();
    }
  )
)
  1. 调整_getRecord()逻辑,接口返回数据后直接赋值给historyList,不要做追加操作:
Future _getRecord() async {
  // 此处替换为你实际的接口请求逻辑
  final apiResponse = await requestLeaveHistoryApi();
  // 直接全量赋值,不要用add/addAll做增量追加
  historyList = apiResponse.map((item) => leaveHistory.fromJson(item)).toList();
  return historyList;
}

内容的提问来源于stack exchange,提问作者TimeToCode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 11:39:00