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

Flutter对象列表映射时TextEditingController.text返回空值问题

问题分析与解决方案

你遇到的核心问题有两个:

1. 打印逻辑错误导致输出空值

在点击"Form Field with Text Output"按钮的回调中,map函数的代码块没有返回值,导致生成的迭代器元素都是null,所以控制台看不到输入内容。

2. 自定义对象与组件的定义不符合Dart最佳实践(潜在风险)

  • custom_formObject中使用late变量初始化控制器,存在潜在的初始化顺序问题
  • CustomFormField的控制器属性定义为var,不符合StatefulWidget属性应不可变的原则

修复后的代码

1. 修正自定义表单对象

class CustomFormObject {
  final String foText;
  final TextEditingController foController;

  CustomFormObject({
    required this.foText,
  }) : foController = TextEditingController(); // 使用初始化列表创建控制器
}

2. 修正页面中的打印逻辑

将按钮回调修改为:

ElevatedButton(
  onPressed: () {
    // 使用箭头函数明确返回文本,同时转为List方便查看
    print(formFieldList.map((field) => field.foController.text).toList());
  },
  child: const Text("Form Field with Text Output")
),

3. 修正自定义表单字段组件

将控制器属性改为final,移除无用的newValue变量:

class CustomFormField extends StatefulWidget {
  final String cffText;
  final TextEditingController cffController; // 改为final,遵循Dart规范

  const CustomFormField({
    Key? key,
    required this.cffText,
    required this.cffController,
  }) : super(key: key);

  @override
  State<CustomFormField> createState() => _CustomFormFieldState();
}

class _CustomFormFieldState extends State<CustomFormField> {
  @override
  void initState() {
    super.initState();
    widget.cffController.addListener(() => setState(() {}));
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 10.0),
      child: TextFormField(
        keyboardType: TextInputType.emailAddress,
        textInputAction: TextInputAction.done,
        style: TextStyle(color: Theme.of(context).colorScheme.onPrimaryContainer),
        decoration: InputDecoration(
          labelText: widget.cffText,
          suffixIcon: widget.cffController.text.isEmpty
              ? const SizedBox(width: 0)
              : IconButton(
                  icon: const Icon(Icons.close),
                  onPressed: () => widget.cffController.clear(),
                  color: Theme.of(context).colorScheme.onPrimary,
                  iconSize: 14.0,
                ),
          labelStyle: TextStyle(
            color: Theme.of(context).colorScheme.secondary,
          ),
          enabledBorder: OutlineInputBorder(
            borderRadius: const BorderRadius.all(Radius.circular(10.0)),
            borderSide: BorderSide(color: Theme.of(context).colorScheme.secondary, width: 0.0),
          ),
          disabledBorder: OutlineInputBorder(
            borderRadius: const BorderRadius.all(Radius.circular(10.0)),
            borderSide: BorderSide(color: Theme.of(context).colorScheme.outline, width: 0.0),
          ),
          focusedBorder: OutlineInputBorder(
            borderRadius: const BorderRadius.all(Radius.circular(10.0)),
            borderSide: BorderSide(color: Theme.of(context).colorScheme.secondary, width: 1.0),
          ),
          errorBorder: OutlineInputBorder(
            borderRadius: const BorderRadius.all(Radius.circular(10.0)),
            borderSide: BorderSide(color: Theme.of(context).colorScheme.error, width: 0.0),
          ),
          focusedErrorBorder: OutlineInputBorder(
            borderRadius: const BorderRadius.all(Radius.circular(10.0)),
            borderSide: BorderSide(color: Theme.of(context).colorScheme.error, width: 1.0),
          ),
        ),
        controller: widget.cffController,
      ),
    );
  }
}

4. 修正页面中的组件映射

同步修改变量名(遵循Dart命名规范):

List<CustomFormObject> formFieldList = [
  CustomFormObject(foText: "Email"),
  CustomFormObject(foText: "UserName"),
];

// ...

Column(
  mainAxisAlignment: MainAxisAlignment.center,
  children: formFieldList.map((field) => CustomFormField(
    cffText: field.foText,
    cffController: field.foController,
  )).toList(),
),

修复后,点击对应按钮就能正常打印出列表中表单字段的输入内容了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 06:16:08