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

Flutter报错'(dynamic) => Null'非TextEditingController?子类型 控制器存值为null

问题根因

  • 类型错误type '(dynamic) => Null' is not a subtype of 'TextEditingController?'的直接原因是:你给TextField的controller属性传入了匿名函数,该属性要求接收TextEditingController类型的实例,二者类型不匹配。
  • 姓名和邮箱输入值同步的原因:你没有给三个输入框分别绑定对应的控制器,姓名和邮箱字段错误共用了_emailController。
  • 保存到数据库的值全为null的原因:你在build中定义的String name, email, contact三个变量全程没有赋值,传入updateData的就是三个未初始化的空值。
  • 冗余代码:initState中给三个控制器加的手动设置光标逻辑属于多余代码,Flutter原生控制器已经自动处理光标定位逻辑。

修复步骤

1. 改造通用输入框方法,新增控制器传参

直接给buildTextFormField新增控制器参数,不需要通过isPhone/isEmail判断绑定哪个控制器,避免逻辑混乱:

Widget buildTextFormField(
  String labelText,
  String placeholder,
  bool isPhone,
  bool isEmail,
  TextEditingController controller, // 新增控制器参数
) {
  return Padding(
    padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 10),
    child: TextField(
      // 删除原错误的onSubmitted逻辑
      controller: controller, // 直接绑定传入的控制器
      obscureText: isPhone ? showPhone : false,
      decoration: InputDecoration(
        suffixIcon: isPhone
            ? IconButton(
                onPressed: () => setState(() => showPhone = !showPhone),
                icon: Icon(
                  Icons.remove_red_eye,
                  color: Red,
                ),
              )
            : null,
        contentPadding: EdgeInsets.only(bottom: 3),
        labelText: labelText,
        labelStyle: TextStyle(
          fontSize: 16,
          fontWeight: FontWeight.bold,
          color: Aqua,
        ),
        floatingLabelBehavior: FloatingLabelBehavior.always,
        hintText: placeholder,
        hintStyle: TextStyle(
          fontSize: 18,
          fontWeight: FontWeight.bold,
          color: Cyan,
        ),
      ),
      // 修正键盘类型逻辑,姓名字段用普通文本键盘
      keyboardType: isPhone 
          ? TextInputType.phone 
          : isEmail 
              ? TextInputType.emailAddress 
              : TextInputType.text,
    ),
  );
}

2. 调用输入框时分别传入对应控制器

// 姓名字段
buildTextFormField(
  "Full Name",
  userData.fname ?? "Enter Full Name here...",
  false,
  false,
  _nameController, // 传入姓名专属控制器
),
addVertical(15),
// 联系方式字段
buildTextFormField(
  "Contact",
  userData.contact ?? "020 *** ****",
  true,
  false,
  _phoneController, // 传入手机号专属控制器
),
addVertical(15),
// 邮箱字段
buildTextFormField(
  "E-mail",
  userData.email ?? "emaple123@gmail.com",
  false,
  true,
  _emailController, // 传入邮箱专属控制器
),

3. 修改保存逻辑,从控制器读取输入值

删除原未赋值的name/email/contact变量,直接从对应控制器取文本:

onPressed: () async {
  if (_formKey.currentState.validate()) {
    setState(() => loading = true);
    dynamic result = await _auth.currentUser;
    if (result != null) {
      await Database(uid: doc.uid).updateData(
        _nameController.text.trim(), // 读姓名控制器的输入值
        _emailController.text.trim(), // 读邮箱控制器的输入值
        _phoneController.text.trim(), // 读手机号控制器的输入值
      );
      Toast.show(
        "Your details have been successfully updated!",
        context,
        duration: Toast.LENGTH_LONG,
        gravity: Toast.BOTTOM,
      );
      setState(() => loading = false);
      Navigator.push(
          context,
          MaterialPageRoute(
              builder: (context) => Homepage()));
    } else {
      Toast.show(
        "Please try again later",
        context,
        gravity: Toast.BOTTOM,
        duration: Toast.LENGTH_LONG,
      );
    }
  }
},

4. 删除冗余代码

删掉initState中三个控制器的addListener相关代码,不需要手动处理光标逻辑。


内容的提问来源于stack exchange,提问作者George Jonathan Osafo-Osei

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 09:27:02