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

Flutter中TextFormField从JSON数组取值后无法修改内容求助

解决Flutter TextFormField编辑后关闭键盘恢复初始值的问题

问题场景

从JSON数组列表读取值并显示到TextFormField后,编辑输入框内容时,每次关闭键盘都会自动恢复为JSON中的初始值。

核心原因

这个问题的本质是TextFormField没有和状态变量做双向绑定,而是直接引用了JSON中的原始静态值。当键盘收起触发组件重建(比如布局重绘)时,TextFormField会重新读取JSON的初始值,覆盖用户编辑后的内容。

两种可行解决方案

方案1:使用TextEditingController(推荐)

通过控制器直接管理输入框的文本内容,初始化时将JSON值赋值给控制器,后续用户输入会自动同步到控制器,组件重建时也会读取控制器中的最新值。

class JsonFormPage extends StatefulWidget {
  final List<dynamic> jsonData;

  const JsonFormPage({super.key, required this.jsonData});

  @override
  State<JsonFormPage> createState() => _JsonFormPageState();
}

class _JsonFormPageState extends State<JsonFormPage> {
  late List<TextEditingController> _inputControllers;

  @override
  void initState() {
    super.initState();
    // 从JSON数据初始化控制器
    _inputControllers = widget.jsonData.map((item) {
      return TextEditingController(text: item['content'].toString());
    }).toList();
  }

  @override
  void dispose() {
    // 务必释放控制器资源,避免内存泄漏
    for (var controller in _inputControllers) {
      controller.dispose();
    }
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: _inputControllers.length,
      itemBuilder: (context, index) {
        return Padding(
          padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
          child: TextFormField(
            controller: _inputControllers[index],
            decoration: InputDecoration(
              labelText: '输入项 ${index + 1}',
              border: const OutlineInputBorder(),
            ),
          ),
        );
      },
    );
  }
}

方案2:使用状态变量+onChanged回调

将JSON初始值存入状态变量,通过onChanged回调实时更新状态,确保组件重建时读取的是更新后的状态值而非原始JSON值。

class JsonFormPage extends StatefulWidget {
  final List<dynamic> jsonData;

  const JsonFormPage({super.key, required this.jsonData});

  @override
  State<JsonFormPage> createState() => _JsonFormPageState();
}

class _JsonFormPageState extends State<JsonFormPage> {
  late List<String> _inputValues;

  @override
  void initState() {
    super.initState();
    // 从JSON初始化状态变量
    _inputValues = widget.jsonData.map((item) => item['content'].toString()).toList();
  }

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: _inputValues.length,
      itemBuilder: (context, index) {
        return Padding(
          padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
          child: TextFormField(
            initialValue: _inputValues[index],
            onChanged: (newValue) {
              setState(() {
                _inputValues[index] = newValue;
              });
            },
            decoration: InputDecoration(
              labelText: '输入项 ${index + 1}',
              border: const OutlineInputBorder(),
            ),
          ),
        );
      },
    );
  }
}

关键注意事项

  • 禁止直接在initialValue中使用jsonData[index]['content']这类原始JSON值,否则每次组件重建都会重置输入框内容
  • 使用TextEditingController时必须在dispose方法中释放资源
  • 复杂表单场景建议结合Provider、Riverpod等状态管理库统一管理输入状态

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 09:44:54