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

使用GetX与GetBuilder时TextFormField值无法更新的问题

问题原因

你遇到的问题是TextFormField的initialValue仅在组件首次构建时生效,后续即使通过update()触发GetBuilder重新渲染,输入框也不会读取新的initialValue,因此内容无法更新。而Row里的Text组件会在每次数据变化时重新渲染,所以能正常显示最新值。

解决方案

为每个动态生成的TextFormField绑定TextEditingController,通过控制器直接控制输入框的文本内容,这样批量赋值时只需更新控制器的text属性,就能同步刷新输入框内容。

1. 修改GetX控制器

添加控制器列表维护每个输入框的TextEditingController,并在批量赋值时同步更新控制器内容:

import 'dart:convert';
import 'package:get/get.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';

class LabourBulkController extends GetxController {
  List workersList = [];
  List<TextEditingController> amountControllers = []; // 新增:存储每个输入框的控制器
  bool loading = false;

  getActiveLabours() async {
    loading = true;
    update(); // 先更新加载状态
    SharedPreferences prefs = await SharedPreferences.getInstance();
    var token = prefs.getString("token");
    var response = await http.get(
        Uri.parse("xxxxxxxxxxxxxxxxxxxxxxx"),
        headers: {'Authorization': 'Bearer $token'});
    var data = jsonDecode(response.body);
    
    workersList.clear();
    amountControllers.clear(); // 清空旧控制器
    for (var i = 0; i < data['data'].length; i++) {
      Map customerData = {
        "id": data['data'][i]['worker_id'],
        "name": data['data'][i]['worker_name'],
        "amount": 0,
      };
      workersList.add(customerData);
      amountControllers.add(TextEditingController(text: '0')); // 初始化控制器
    }
    loading = false;
    update();
  }

  assignAtOnce(String amount) {
    for (var i = 0; i < workersList.length; i++) {
      workersList[i]['amount'] = amount;
      amountControllers[i].text = amount; // 同步更新控制器文本
    }
    update();
  }

  // 新增:页面销毁时释放控制器资源
  void disposeControllers() {
    amountControllers.forEach((controller) => controller.dispose());
  }
}

2. 修改Widget代码中的TextFormField

替换initialValue为控制器绑定:

GetBuilder<LabourBulkController>(builder: (dx) {
  return ListView.builder(
      itemCount: dx.workersList.length,
      physics: const NeverScrollableScrollPhysics(),
      shrinkWrap: true,
      itemBuilder: (BuildContext context, int index) {
        return Card(
          child: Padding(
            padding: const EdgeInsets.all(8.0),
            child: Column(children: [
              Row(
                crossAxisAlignment: CrossAxisAlignment.center,
                mainAxisAlignment: MainAxisAlignment.start,
                children: [
                  const SizedBox(width: 10, height: 50),
                  const Icon(FeatherIcons.user),
                  const SizedBox(width: 20),
                  Text(
                    "${dx.workersList[index]['name']} | ${dx.workersList[index]['amount'].toString()}",
                    style: const TextStyle(fontSize: 18),
                  ),
                ],
              ),
              TextFormField(
                keyboardType: TextInputType.number,
                decoration: const InputDecoration(
                    border: OutlineInputBorder(),
                    hintText: "Wages",
                    prefixIcon: Icon(Icons.wallet, color: Colors.blue)),
                controller: dx.amountControllers[index], // 使用控制器绑定
                onChanged: (value) {
                  dx.workersList[index]['amount'] = value;
                  dx.update(); // 同步更新其他组件(如上方的Text)
                },
              )
            ]),
          ),
        );
      });
}),

3. 页面销毁时释放资源

在页面的State类中添加dispose方法,释放控制器资源避免内存泄漏:

@override
void dispose() {
  _bulkController.disposeControllers();
  super.dispose();
}

效果说明

修改后,当你在AlertDialog的输入框中输入内容时,assignAtOnce方法会同时更新workersList数据和所有输入框控制器的文本,GetBuilder触发渲染后,所有TextFormField会同步显示最新的批量赋值内容,Row里的Text也会继续正常更新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 01:01:20