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
相关产品推荐
相关产品推荐

