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

Flutter中ListView.builder删除元素时总是删除最后一项的问题求助

问题解决:ModalBottomSheet中ListView.builder删除项视觉异常

问题原因

  1. ListView组件复用逻辑问题:ListView.builder会复用列表项组件,若未给每个项设置唯一Key,Flutter无法准确识别每个项的身份,删除操作后会错误复用组件,导致视觉上显示最后一项被删除。
  2. TextFormField内容未实时同步:initialValue仅在组件初始化时生效,后续数据变化不会自动更新输入框内容,进一步加剧了显示与实际数据的不匹配。

解决方案

  1. 为每个列表项设置唯一Key,让Flutter能精准跟踪项的状态。
  2. 使用TextEditingController替代initialValue,确保输入框内容随数据变化实时更新。

修改后的代码示例

ListView.builder(
  primary: false,
  itemCount: price.length,
  itemBuilder: ((context, index) {
    // 为输入框创建控制器,绑定当前数据
    final priceIdController = TextEditingController(
      text: price[index].priceID != -1 ? price[index].priceID.toString() : null,
    );
    final priceCountController = TextEditingController(
      text: price[index].priceID != -1 ? price[index].priceCount.toString() : null,
    );

    // 给列表项设置唯一Key(以priceID作为唯一标识)
    return Column(
      key: ValueKey(price[index].priceID),
      children: [
        SizedBox(
          height: 50,
          child: Row(
            mainAxisAlignment: MainAxisAlignment.start,
            children: [
              SizedBox(
                height: 45,
                width: 60,
                child: TextFormField(
                  controller: priceIdController,
                  textInputAction: TextInputAction.next,
                  decoration: InputDecoration(
                    enabledBorder: OutlineInputBorder(
                      borderRadius: BorderRadius.circular(10),
                      borderSide: const BorderSide(
                        color: Color.fromARGB(204, 199, 199, 199),
                      ),
                    ),
                    border: OutlineInputBorder(
                      borderRadius: BorderRadius.circular(10),
                    ),
                  ),
                ),
              ),
              const SizedBox(width: 15),
              SizedBox(
                height: 45,
                width: 100,
                child: TextFormField(
                  controller: priceCountController,
                  textInputAction: TextInputAction.done,
                  decoration: InputDecoration(
                    enabledBorder: OutlineInputBorder(
                      borderRadius: BorderRadius.circular(10),
                      borderSide: const BorderSide(
                        color: Color.fromARGB(204, 199, 199, 199),
                      ),
                    ),
                    border: OutlineInputBorder(
                      borderRadius: BorderRadius.circular(10),
                    ),
                  ),
                ),
              ),
              SizedBox(width: MediaQuery.of(context).size.width * 0.35),
              IconButton(
                icon: const Icon(Icons.cancel_outlined),
                color: Colors.redAccent,
                onPressed: () {
                  setState(() {
                    price.removeAt(index);
                  });
                },
              ),
            ],
          ),
        ),
      ],
    );
  }),
)

补充说明

  • 若priceID存在重复情况,可改用UUID或ValueKey('${price[index].priceID}-$index')这类组合标识作为唯一Key。
  • 确保setState能触发父页面的状态更新,若ModalBottomSheet是通过showModalBottomSheet弹出,需保证状态管理逻辑能覆盖到列表刷新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 00:57:13