Flutter如何获取TextField输入值?TextEditingController跨组件调用报错怎么解决
你遇到的两处报错分别来自两个典型的Flutter作用域问题:
- 自定义输入组件是独立的类,无法直接访问父组件State中定义的控制器
loginAct方法不在_LoginState类的作用域内,同时你提交数据时直接传入了控制器实例而非输入的文本值
步骤1:修改自定义输入组件,增加控制器入参
给TextInputField和PasswordInput都新增必填的TextEditingController构造参数,示例如下:
class TextInputField extends StatelessWidget { // 新增控制器属性 final TextEditingController controller; const TextInputField({ Key? key, // 要求调用时必须传入控制器 required this.controller, }) : super(key: key); @override Widget build(BuildContext context) { Size size = MediaQuery.of(context).size; return Padding( padding: const EdgeInsets.symmetric(vertical: 10.0), child: Container( height: size.height * 0.08, width: size.width * 0.8, decoration: BoxDecoration( color: Colors.grey[500], borderRadius: BorderRadius.circular(16), ), child: TextField( // 替换为传入的控制器 controller: controller, decoration: InputDecoration( border: InputBorder.none, prefixIcon: Padding( padding: const EdgeInsets.symmetric(horizontal: 20.0), child: Icon( FontAwesomeIcons.user, size: 28, color: Colors.black54, ), ), hintText: 'id', ), ), ), ); } }
PasswordInput按照同样的逻辑修改即可。
步骤2:父组件调用时传入对应控制器
在_LoginState中使用自定义输入组件时,把提前定义好的控制器传入:
class _LoginState extends State<LoginScreen> { final userId = TextEditingController(); final userPass = TextEditingController(); @override Widget build(BuildContext context) { return Column( children: [ // 传入账号控制器 TextInputField(controller: userId), // 传入密码控制器 PasswordInput(controller: userPass), LoginButton() ], ); } }
步骤3:调整登录方法位置和取值逻辑
把loginAct方法放到_LoginState类内部,同时通过控制器的text属性获取输入的文本值:
class _LoginState extends State<LoginScreen> { final userId = TextEditingController(); final userPass = TextEditingController(); // 登录方法放到State内部 void loginAct() async { var data = { "user_id": userId.text, "user_pass": userPass.text, }; // 后续接口请求逻辑 } @override void dispose() { // 页面销毁时释放控制器,避免内存泄漏 userId.dispose(); userPass.dispose(); super.dispose(); } // 原有build逻辑 }
内容的提问来源于stack exchange,提问作者Sanghun Yang
相关产品推荐
相关产品推荐

