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

Flutter中用GetX与无状态组件按需生成TextField的问题排查

Flutter中GetX结合Stateless Widget按需生成TextField的问题修复

代码错误分析

当前点击「+」按钮无法添加新TextField的核心问题是状态监听范围错误:

  • 仅用Obx包裹了单个TextField,但ListView.builder的itemCount直接读取controller.textFieldControllerList.length,未被GetX的状态监听覆盖。当RxList添加新元素时,itemCount的变化不会触发UI重建,导致ListView无法渲染新的列表项。
  • 额外问题:在StatelessWidget的成员变量中直接调用Get.put()不是最佳实践,可能导致重复注入控制器。

正确实现方式

核心修改点

  1. 将Obx的范围扩大到ListView.builder,确保列表的itemCount和列表项都能响应RxList的变化。
  2. 使用Get.find()获取已注入的控制器,避免重复初始化。

修改后的屏幕文件代码

import 'package:flutter/material.dart';
import 'package:dynamic_lists/controllers/2_ListWithInputBoxGetxController.dart';
import 'package:get/get.dart';

class ListWithInputBoxGetx extends StatelessWidget {
  ListWithInputBoxGetx({Key? argKey, this.title}) : super(key: argKey);

  final String? title;
  // 使用Get.find()获取已注入的控制器
  final ListWithInputBoxGetxController controller = Get.find();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(title!)),
      body: Padding(
        padding: const EdgeInsets.all(10),
        child: SingleChildScrollView(
          child: Column(
            children: <Widget>[
              Container(
                height: 400,
                color: Colors.limeAccent,
                // 用Obx包裹整个ListView.builder,监听RxList的变化
                child: Obx(() => ListView.builder(
                      itemCount: controller.textFieldControllerList.length,
                      prototypeItem: const TextField(),
                      itemBuilder: ((context, index) {
                        return TextField(
                          controller: controller.getTextFieldController(index),
                        );
                      }),
                    )),
              ),
              const SizedBox(height: 10),
              ElevatedButton(
                onPressed: controller.addTextField,
                child: const Text("+"),
              ),
              const SizedBox(height: 10),
              ElevatedButton(
                onPressed: controller.submit,
                child: const Icon(Icons.sailing),
              )
            ],
          ),
        ),
      ),
    );
  }
}

修改后的控制器文件代码

(控制器核心逻辑无问题,仅优化类型声明并补充内存清理逻辑)

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

class ListWithInputBoxGetxController extends GetxController {
  RxList<TextEditingController> textFieldControllerList = <TextEditingController>[].obs;

  // 为参数添加类型声明,增强代码健壮性
  TextEditingController getTextFieldController(int argIndex) {
    return textFieldControllerList[argIndex];
  }

  void addTextField() {
    textFieldControllerList.add(TextEditingController());
  }

  void submit() {
    // 示例:获取所有输入框内容
    final inputs = textFieldControllerList.map((ctrl) => ctrl.text).toList();
    print("提交的输入内容:$inputs");
  }

  // 页面销毁时清理控制器,避免内存泄漏
  @override
  void onClose() {
    for (var ctrl in textFieldControllerList) {
      ctrl.dispose();
    }
    textFieldControllerList.clear();
    super.onClose();
  }
}

额外注意事项

  • 确保在使用Get.find()之前,控制器已被注入。可在应用启动时全局注入,或在父Widget中提前调用Get.put(ListWithInputBoxGetxController())。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 18:14:58