Flutter技术求助:隐藏虚拟键盘后TextField值为空
问题原因与解决方案
嘿,这个问题的核心原因其实很明确——你把email和password这两个变量声明在了build方法内部!
为什么会出现这种奇怪的现象?
Flutter的build方法会在UI需要更新时重新执行,比如当你隐藏虚拟键盘时,屏幕的可用空间发生变化,会触发页面重绘,build方法就会重新跑一遍。这时候你在build里定义的String email = '';和String password = '';会被重新初始化为空字符串,所以点击按钮时自然打印不出内容。
而当虚拟键盘打开时,你输入完直接点击按钮,这时候页面还没触发重绘,变量还保留着你输入的值,所以能正常打印。
修复步骤
只需要把这两个变量移到_StudentLoginScreenState类的成员变量位置,让它们的生命周期和页面状态绑定,而不是每次build都重置:
class _StudentLoginScreenState extends State<StudentLoginScreen> { // 把变量移到类的成员区域,初始化一次即可 String email = ''; String password = ''; @override Widget build(BuildContext context) { final AuthService _authService = AuthService(); Size size = MediaQuery.of(context).size; // 删掉这里的变量声明! // String email = ''; // String password = ''; return Scaffold( // 后续代码保持不变,建议在onChanged里加上setState(好习惯) body: SafeArea( child: ListView( children: <Widget>[ // ... RoundedInputField( hintText: "Email", onChanged: (val) { setState(() { // 加上setState,确保状态变化被Flutter感知 email = val; }); }, ), // ... RoundedInputField( hintText: "Password", boolean: true, onChanged: (val) { setState(() { password = val; }); }, ), // ... FlatButton( onPressed: () async { print(email); print(password); }, // ... ), ], ), ), ); } }
额外优化建议
如果你的表单逻辑后续会更复杂(比如表单验证、清空输入等),推荐使用TextEditingController来管理输入内容,这样操作会更灵活,还能避免一些状态同步问题:
class _StudentLoginScreenState extends State<StudentLoginScreen> { // 声明控制器 final TextEditingController _emailController = TextEditingController(); final TextEditingController _passwordController = TextEditingController(); // 记得在页面销毁时释放控制器,防止内存泄漏 @override void dispose() { _emailController.dispose(); _passwordController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final AuthService _authService = AuthService(); Size size = MediaQuery.of(context).size; return Scaffold( backgroundColor: HexColor(studentPrimaryColour), body: SafeArea( child: ListView( children: <Widget>[ // ... // 修改RoundedInputField,让它支持接收controller参数 RoundedInputField( hintText: "Email", controller: _emailController, // 绑定控制器 ), // ... RoundedInputField( hintText: "Password", boolean: true, controller: _passwordController, ), // ... FlatButton( onPressed: () async { // 通过controller获取输入值 print(_emailController.text); print(_passwordController.text); }, // ... ), ], ), ), ); } } // 对应的RoundedInputField修改: class RoundedInputField extends StatefulWidget { final String hintText; final ValueChanged<String> onChanged; final Color color; final bool boolean; final TextEditingController controller; // 添加controller参数 RoundedInputField({ Key key, this.hintText, this.onChanged, this.color, this.boolean = false, this.controller, // 加入参数 }) : super(key: key); @override _RoundedInputFieldState createState() => _RoundedInputFieldState(); } class _RoundedInputFieldState extends State<RoundedInputField> { @override Widget build(BuildContext context) { return TextFieldContainer( child: TextFormField( controller: widget.controller, // 绑定到TextFormField onChanged: widget.onChanged, obscureText: widget.boolean, decoration: InputDecoration( hintText: widget.hintText, border: InputBorder.none, ), ), ); } }
这样不管键盘隐藏与否,输入的值都能被正确保留和获取啦!
内容的提问来源于stack exchange,提问作者Anugrah k
相关产品推荐
相关产品推荐

