Flutter点击按钮或单选框时文本框自动清空问题求助
Flutter文本框点击按钮/单选框后自动清空的解决方案
问题根源
你把所有TextEditingController实例都定义在build方法内部了:
Widget build(BuildContext context1) { TextEditingController getUsername = TextEditingController(); // 其他控制器... }
每次调用setState(单选框切换、按钮点击都会触发),Flutter会重新执行build方法,重新创建所有控制器。新的控制器没有保存之前输入的文本,所以文本框看起来被清空了。
修复方案
将TextEditingController移到_ProfileScreenState类的成员变量位置,让它们在组件生命周期内保持实例不变:
修改后的完整代码
import 'package:flutter/material.dart'; import 'NavDrawer.dart'; class proFile extends StatelessWidget { static const String routeName = '/profile'; const proFile({super.key}); @override build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("Profile"), ), drawer: const NavDrawer(), body: ProfileScreen()); } } class ProfileScreen extends StatefulWidget { const ProfileScreen({super.key}); @override _ProfileScreenState createState() { return _ProfileScreenState(); } } enum Gender { male, female } String getGender=""; class _ProfileScreenState extends State<ProfileScreen> { Gender? _gender = Gender.male; // 控制器定义为类成员变量 late TextEditingController getUsername; late TextEditingController getFName; late TextEditingController getLName; late TextEditingController getPass; late TextEditingController getCPass; late TextEditingController getEmail; late TextEditingController var5; @override void initState() { super.initState(); // 初始化控制器(仅组件创建时执行一次) getUsername = TextEditingController(); getFName = TextEditingController(); getLName = TextEditingController(); getPass = TextEditingController(); getCPass = TextEditingController(); getEmail = TextEditingController(); var5 = TextEditingController(); } @override void dispose() { // 释放控制器资源,避免内存泄漏 getUsername.dispose(); getFName.dispose(); getLName.dispose(); getPass.dispose(); getCPass.dispose(); getEmail.dispose(); var5.dispose(); super.dispose(); } @override Widget build(BuildContext context1) { return SingleChildScrollView( child: Column( children: <Widget>[ Row( children: <Widget>[ Container( margin: EdgeInsets.all(20), child: Text("Enter Your Profile", style: TextStyle(fontSize: 40, color: Colors.black)), ), ], ), // row2 Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Container( height: 50, width: 500, margin: EdgeInsets.all(10), child: TextField( keyboardType: TextInputType.text, controller: getUsername, decoration: InputDecoration( border: const OutlineInputBorder( borderSide: const BorderSide(color: Colors.lightGreen)), labelText: "Enter Your UserName")), ) ], ), // row3 Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Container( height: 50, width: 500, margin: EdgeInsets.all(10), child: TextField( controller: getFName, keyboardType: TextInputType.text, decoration: InputDecoration( border: const OutlineInputBorder( borderSide: const BorderSide(color: Colors.lightGreen)), labelText: "Enter Your First Name")), ) ], ), // row4 Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Container( height: 50, width: 500, margin: EdgeInsets.all(10), child: TextField( controller: getLName, keyboardType: TextInputType.text, decoration: InputDecoration( border: const OutlineInputBorder( borderSide: const BorderSide(color: Colors.lightGreen)), labelText: "Enter Your Last Name")), ) ], ), Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Container( height: 50, width: 500, margin: EdgeInsets.all(10), child: TextField( controller: getPass, keyboardType: TextInputType.text, decoration: InputDecoration( border: const OutlineInputBorder( borderSide: const BorderSide(color: Colors.lightGreen)), labelText: "Enter Your Password")), ) ], ), Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Container( height: 50, width: 500, margin: EdgeInsets.all(10), child: TextField( controller: getCPass, keyboardType: TextInputType.text, decoration: InputDecoration( border: const OutlineInputBorder(), labelText: "Confirm Your Password")), ) ], ), Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Container( height: 50, width: 500, margin: EdgeInsets.all(10), child: TextField( controller: getEmail, keyboardType: TextInputType.text, decoration: InputDecoration( border: const OutlineInputBorder(), labelText: "Enter Your Email")), ) ], ), Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Container( height: 50, width: 400, child:ListTile( title: const Text('Male'), leading: Radio( value: Gender.male, groupValue: _gender, onChanged: (Gender? value) { setState(() { _gender = value; }); }, ), ), ), Container( height: 50, width: 400, child:ListTile( title: const Text('Female'), leading: Radio( value: Gender.female, groupValue: _gender, onChanged: (Gender? value) { setState(() { _gender = value; }); }, ), ), ) ], ), Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Container( height: 100, width: 500, margin: EdgeInsets.all(1), child: TextField( maxLines: 8, controller: var5, keyboardType: TextInputType.text, decoration: InputDecoration( border: const UnderlineInputBorder(borderSide: const BorderSide(color: Colors.lightGreen)), labelText: "")), ) ], ), Row( children: <Widget>[ const SizedBox(height: 55.0, width: 20.0), SizedBox( width: 250.0, height: 70, child: ElevatedButton( child: const Text("Submit!"), style: ElevatedButton.styleFrom( backgroundColor: Colors.green, padding: EdgeInsets.all(20), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20))), onPressed: () { setState(() { String name = getUsername.text; String fname = getFName.text; String lname = getLName.text; String pass = getPass.text; String cpass = getCPass.text; String email = getEmail.text; var5.text="Inputted Result:\nName=$name\nFirst Name=$fname\nLast Name=$lname\nEmail=$email"; }); }, ), ), ]), ], ), ); } }
关键改动说明
- 将所有
TextEditingController从build方法内移到_ProfileScreenState类的成员变量区域,用late关键字延迟初始化 - 在
initState方法中初始化控制器(仅组件创建时执行一次) - 在
dispose方法中释放控制器资源,避免内存泄漏 build方法内直接使用类成员变量的控制器,不再重新创建
这样修改后,每次setState触发重建时,控制器实例会保持不变,文本框的输入内容就不会丢失了。
内容的提问来源于stack exchange,提问作者diabetes_comms
相关产品推荐
相关产品推荐

