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

Flutter动态列表删除异常:调用removeAt()始终删除最后一项求助

Flutter动态列表调用removeAt()删除指定项却总是删除最后一项的解决方案

问题现象

开发支持增删操作的Flutter动态列表时,调用removeAt()方法删除指定索引的项,实际视觉效果总是最后一项被删除。

问题原因

  1. ListView.builder的Widget复用机制:列表项被删除后,Flutter会复用已存在的Widget渲染新列表,但TextField的状态未与对应列表项数据绑定,导致状态错位,视觉上呈现为删除了最后一项。
  2. 缺少唯一标识Key:每个列表项的TextField未设置唯一Key,Flutter无法区分不同的列表项Widget,无法正确维护输入状态与对应数据的关联。

解决方案

给每个TextField绑定唯一Key关联对应数据模型,同时优化增删逻辑确保状态正确更新。以下是修改后的完整代码:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

// 模拟原代码中的ExpenseItemModel类
class ExpenseItemModel {
  String? inputValue;
  ExpenseItemModel({this.inputValue});
}

class TestPage extends StatefulWidget {
  const TestPage({Key? key}) : super(key: key);

  @override
  State<TestPage> createState() => _TestPageState();
}

class _TestPageState extends State<TestPage> {
  List<ExpenseItemModel> expenses =
      List.generate(1, (index) => ExpenseItemModel());

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          const SizedBox(height: 150),
          Expanded(
            child: ListView.builder(
              itemCount: expenses.length,
              itemBuilder: (c, i) {
                final currentItem = expenses[i];
                return Column(
                  children: [
                    Row(
                      children: [
                        IconButton(
                          onPressed: () {
                            if (expenses.length == 1 || i == expenses.length -1) return;
                            setState(() {
                              expenses.removeAt(i);
                            });
                          },
                          icon: const Icon(CupertinoIcons.delete),
                        ),
                        Expanded(
                          child: TextField(
                            key: ValueKey(currentItem), // 绑定唯一Key,关联对应数据模型
                            controller: TextEditingController(text: currentItem.inputValue),
                            onChanged: (val) {
                              setState(() {
                                currentItem.inputValue = val;
                                if (i == expenses.length -1) {
                                  expenses.add(ExpenseItemModel());
                                }
                              });
                            },
                            decoration: InputDecoration(
                              border: border,
                              enabledBorder: border,
                              focusedBorder: border,
                            ),
                          ),
                        ),
                        const SizedBox(width: 50),
                      ],
                    ),
                    const SizedBox(height: 10),
                  ],
                );
              },
            ),
          ),
        ],
      ),
    );
  }

  final border = OutlineInputBorder(
    borderRadius: BorderRadius.circular(8),
  );
}

关键修改说明

  • 添加唯一Key:通过ValueKey(currentItem)为每个TextField设置唯一标识,让Flutter能准确区分不同列表项,避免Widget复用导致的状态错位。
  • 绑定数据模型:使用TextEditingController将输入框内容与ExpenseItemModel的字段关联,确保每个输入框的内容正确对应到对应数据项。
  • 优化状态更新:将数据修改操作包裹在setState()内,确保状态变更能触发正确的UI重建。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 03:44:57