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

Flutter嵌套ListView.builder的控制器独立实现问题

Flutter嵌套ListView.builder中TextEditingController独立化解决方案

问题根源

原代码使用全局的xControllers和yControllers列表存储所有子项控制器,存在两个核心问题:

  • 每次构建子列表时都会重复向全局列表添加新控制器,导致列表长度持续膨胀,索引对应关系混乱。
  • 不同主列表项的子列表使用相同的sIndex(子项索引)获取全局控制器,导致同位置子项共享同一控制器,输入内容同步。

解决方案

1. 重构数据结构,绑定控制器与子项

修改mainList结构,让每个子项自带专属的TextEditingController,确保每个子项的控制器完全独立。

2. 修正控制器创建与使用逻辑

仅在添加子列表项时创建专属控制器;子列表itemBuilder中直接使用子项自带的控制器,不再依赖全局列表。

3. 销毁控制器避免内存泄漏

页面销毁时,遍历所有主列表项的子项,销毁对应的控制器。

修改后的完整代码

import 'package:flutter/material.dart';

class NestedLists extends StatefulWidget {
  const NestedLists({super.key});

  @override
  State<NestedLists> createState() => _NestedListsState();
}

class _NestedListsState extends State<NestedLists> {
  // 重构数据结构:每个主项包含子项列表,每个子项自带x/y控制器
  List<Map<String, dynamic>> mainList = [];

  @override
  void dispose() {
    // 销毁所有控制器,避免内存泄漏
    for (var mainItem in mainList) {
      for (var subItem in mainItem['sub_list']) {
        subItem['xController'].dispose();
        subItem['yController'].dispose();
      }
    }
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        body: Padding(
          padding: const EdgeInsets.all(10.0),
          child: SingleChildScrollView(
            child: Column(
              children: [
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    const Text('Add Nested Lists'),
                    ElevatedButton(
                      onPressed: () {
                        setState(() {
                          mainList.add({
                            'sub_list': [],
                          });
                        });
                      },
                      child: const Text('Add another List'),
                    ),
                  ],
                ),
                if (mainList.isNotEmpty)
                  ListView.builder(
                    shrinkWrap: true,
                    itemCount: mainList.length,
                    itemBuilder: (BuildContext context, int index) => Padding(
                      padding: const EdgeInsets.all(10.0),
                      child: Card(
                        child: Padding(
                          padding: const EdgeInsets.all(20.0),
                          child: Column(
                            children: [
                              Row(
                                mainAxisAlignment:
                                    MainAxisAlignment.spaceBetween,
                                children: [
                                  Text(
                                    'Index $index',
                                  ),
                                  ElevatedButton(
                                    onPressed: () {
                                      setState(() {
                                        // 添加子项时直接创建专属控制器
                                        mainList[index]['sub_list'].add({
                                          'xController': TextEditingController(text: ''),
                                          'yController': TextEditingController(text: ''),
                                        });
                                      });
                                    },
                                    child: const Text('Add Sub List'),
                                  ),
                                ],
                              ),
                              if (mainList[index]['sub_list'].isNotEmpty)
                                Padding(
                                  padding: const EdgeInsets.all(20.0),
                                  child: ListView.builder(
                                    shrinkWrap: true,
                                    itemCount:
                                        mainList[index]['sub_list'].length,
                                    itemBuilder:
                                        (BuildContext context, int sIndex) {
                                      // 直接使用当前子项自带的控制器
                                      final subItem = mainList[index]['sub_list'][sIndex];
                                      return Row(
                                        children: [
                                          Expanded(
                                              child: TextFormField(
                                            controller: subItem['xController'],
                                            decoration: const InputDecoration(
                                              border: OutlineInputBorder(),
                                            ),
                                          )),
                                          const SizedBox(
                                            width: 50,
                                          ),
                                          Expanded(
                                            child: TextFormField(
                                              controller: subItem['yController'],
                                              decoration: const InputDecoration(
                                                border: OutlineInputBorder(),
                                              ),
                                            ),
                                          ),
                                        ],
                                      );
                                    },
                                  ),
                                ),
                            ],
                          ),
                        ),
                      ),
                    ),
                  )
              ],
            ),
          ),
        ),
      ),
    );
  }
}

关键修改说明

  • 数据结构重构:每个子列表项包含xController和yController两个专属控制器,彻底隔离不同子项的控制器。
  • 控制器创建时机:仅在点击"Add Sub List"时创建控制器,避免构建时重复创建导致的索引混乱。
  • 内存管理:在dispose方法中销毁所有控制器,符合Flutter内存管理规范。
  • 控制器使用:子列表项直接从当前主项的子列表中获取对应控制器,避免跨主项共享控制器的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 15:27:47