Flutter自定义TextFieldName组件:validator与controller失效求助
问题描述
我有一个Flutter模板,原本使用DInput组件,替换为自定义的TextFieldName组件后,validator和controller功能均失效。尝试过多种修复方法(如导入d_input的validator)但仍未解决,相关代码如下:
原组件代码
Expanded( child: DInput( controller: edtUsername, fillColor: Colors.white70, hint: 'Username', radius: BorderRadius.circular(10), validator: (input) => input == '' ? "Don't empty" : null, ), ),
替换后的调用代码
TextFieldName(controller: edtUsername, validator: (value) { if (value == null || value.isEmpty) { return 'Please enter your name'; } return null; }),
TextFieldName组件代码
import 'package:flutter/material.dart'; class TextFieldName extends StatelessWidget { final TextEditingController controller; final String? Function(String?) validator; const TextFieldName({ Key? key, required this.controller, required this.validator, }) : super(key: key); @override Widget build(BuildContext context) { return Container( width: 300, height: 40, decoration: ShapeDecoration( color: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(15), ), ), child: TextField( controller: controller, decoration: InputDecoration( prefixIcon: Container( width: 20, height: 20, child: Image.asset( 'assets/icon/User.png', width: 20, height: 20, ), ), hintText: 'Enter your name', hintStyle: TextStyle( color: Color(0xFFA1A1A1), fontFamily: 'RobotoSlab', fontWeight: FontWeight.normal, fontSize: 12, ), contentPadding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0), border: OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(15)), ), ), ), ); } }
解决方案
问题根源在于两个核心点:
- Validator未绑定到验证逻辑:原生
TextField不支持validator参数,这个属性属于TextFormField(表单专用输入组件)。自定义组件里必须用TextFormField替代TextField,并将传入的validator赋值给它的对应参数。 - 表单上下文缺失:验证功能需要依托
Form组件和GlobalKey<FormState>来触发,单独使用TextFormField无法自动触发验证。
修改后的TextFieldName组件
import 'package:flutter/material.dart'; class TextFieldName extends StatelessWidget { final TextEditingController controller; final String? Function(String?) validator; const TextFieldName({ Key? key, required this.controller, required this.validator, }) : super(key: key); @override Widget build(BuildContext context) { return Container( width: 300, height: 40, decoration: ShapeDecoration( color: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(15), ), ), child: TextFormField( // 替换为TextFormField controller: controller, validator: validator, // 绑定传入的验证器 decoration: InputDecoration( prefixIcon: Container( width: 20, height: 20, child: Image.asset( 'assets/icon/User.png', width: 20, height: 20, ), ), hintText: 'Enter your name', hintStyle: TextStyle( color: Color(0xFFA1A1A1), fontFamily: 'RobotoSlab', fontWeight: FontWeight.normal, fontSize: 12, ), contentPadding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0), border: OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(15)), ), ), ), ); } }
正确的表单使用示例
确保组件包裹在Form内,并通过全局键触发验证:
final _formKey = GlobalKey<FormState>(); final edtUsername = TextEditingController(); @override Widget build(BuildContext context) { return Form( key: _formKey, child: Column( children: [ TextFieldName( controller: edtUsername, validator: (value) { if (value == null || value.isEmpty) { return 'Please enter your name'; } return null; }, ), ElevatedButton( onPressed: () { if (_formKey.currentState!.validate()) { // 验证通过,处理输入值 print(edtUsername.text); } }, child: Text('Submit'), ), ], ), ); }
修改后,validator会正常触发验证逻辑,controller也能正确获取输入内容。
内容的提问来源于stack exchange,提问作者HollowX7
相关产品推荐
相关产品推荐

