Flutter点击密码框suffixIcon时邮箱TextField内容被清空问题
问题根因
邮箱输入框内容被清空的核心原因是**TextEditingController的定义位置错误**:
你将_email、_pass两个控制器实例写在了build方法内部。点击密码显隐按钮时会触发AuthProvider状态更新,进而调用当前页面的build方法重新执行,每次build执行都会重新生成新的控制器实例,绑定到输入框后就会把原有输入内容重置。
另外你的代码还存在两个隐性问题:
- 自定义的
emailText、passwordText方法虽然声明了controller入参,但方法内部没有使用传入的参数,直接硬编码引用了build内的局部控制器变量,作用域逻辑错误 - 存在多处拼写错误:
chilfren应为children、TextFiled应为TextField,会直接导致编译或布局异常。
修复方案
- 将
TextEditingController实例移到对应State类的成员变量位置,不要在build方法内初始化,同时在dispose生命周期中释放控制器,避免内存泄漏 - 修正自定义输入框组件方法的逻辑,使用传入的controller参数绑定输入框,不要硬编码引用局部变量
- 修正所有拼写错误
修复后的可参考代码:
class LoginPage extends StatefulWidget { const LoginPage({super.key}); @override State<LoginPage> createState() => _LoginPageState(); } class _LoginPageState extends State<LoginPage> { // 控制器移到build外,作为State成员变量 final TextEditingController _email = TextEditingController(); final TextEditingController _pass = TextEditingController(); @override void dispose() { // 生命周期结束释放控制器 _email.dispose(); _pass.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Column( // 修正拼写错误 children:[ emailText(_email), passwordText(_pass) ] ); } //===Widgets Method TextField emailText(TextEditingController controller){ return TextField( // 使用传入的controller,不要硬编码局部变量 controller : controller, ); } Consumer passwordText(TextEditingController controller){ return Consumer<AuthProvider>(builder:(context,auth,child){ return TextField( obscureText: auth.isLoginPassowrdHidden, // 使用传入的controller controller : controller, suffixIcon: IconButton( onPressed: () { auth.showLoginFormPassword(); }, icon: Icon( auth.isLoginPassowrdHidden ? Icons.visibility_outlined : Icons.visibility_off_outlined, color: const Color(0xFFBDBDBD), size: 18, )), ); }); } }
补充说明:后续开发中不要在build方法内初始化任何和状态绑定的控制器、焦点节点实例,这类需要跨构建周期保存状态的对象都应当作为State成员变量存储,在initState中初始化、dispose中释放,避免状态刷新时实例重建导致的内容丢失、性能损耗问题。
内容的提问来源于stack exchange,提问作者Sarmed MQ Berwari
相关产品推荐
相关产品推荐

