Flutter中CustomTextField点击后键盘弹出即关闭问题求助
Flutter键盘弹出后立即关闭,无法输入TextField内容
问题描述
点击自定义CustomTextField或原生TextField时,系统键盘短暂弹出后立刻关闭,完全无法输入内容。Debug Console中可看到showSoftInput()日志,但键盘无法保持弹出状态。
已尝试的解决方案
- 依赖更新:检查并更新
pubspec.yaml所有依赖,执行flutter pub get确保依赖为最新版本 - 缓存清理:执行
flutter clean清理缓存后,重新flutter pub get并flutter run构建应用 - 设备/模拟器验证:确认模拟器配置正确,更换多台模拟器测试,问题依旧存在
相关代码
Form及CustomTextField使用代码
Form( key: GlobalKey<FormState>(), child: Column( children: [ CustomTextField( label: 'E-mail', prefixIcon: Icons.email, keyboardType: TextInputType.emailAddress, controller: controller.emailController, validator: controller.validateEmail, ), CustomTextField( label: 'Senha', prefixIcon: Icons.password, isPassword: true, controller: controller.passwordController, validator: controller.validatePassword, keyboardType: TextInputType.text, ), ], ), ),
SigninController代码
import 'package:flutter/material.dart'; import 'package:get/get.dart'; class SigninController extends GetxController { final RxString snackBarMessage = ''.obs; late TextEditingController emailController; late TextEditingController passwordController; @override void onInit() { super.onInit(); emailController = TextEditingController(); passwordController = TextEditingController(); } @override void onClose() { emailController.dispose(); passwordController.dispose(); super.onClose(); } String? validateEmail(String? value) { if (value == null || value.isEmpty) { return 'Required field'; } else if (!RegExp(r'^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,7 }$') .hasMatch(value)) { return 'Invalid email'; } return null; } String? validatePassword(String? value) { if (value == null || value.isEmpty) { return 'Required field'; } else if (value.length < 6) { return 'The password must be at least 6 characters long'; } return null; } }
额外观察
- 即使替换为原生
TextField,问题仍然存在 - 键盘弹出瞬间Debug Console输出
showSoftInput()日志
排查与解决方向
1. 检查页面是否存在不必要的重渲染
键盘弹出时页面布局变化,如果页面因setState或Rx变量更新导致频繁重渲染,会丢失TextField焦点:
- 排查页面中是否有未正确管理的
Rx变量,确认是否有变量在键盘弹出时被意外触发更新 - 使用Flutter DevTools的Performance面板查看页面重渲染频率,确认是否存在异常重建
2. 手动管理焦点节点
绑定焦点节点并手动请求焦点,避免焦点被意外夺走:
final FocusNode _emailFocus = FocusNode(); final FocusNode _passwordFocus = FocusNode(); // 在TextField中绑定焦点 CustomTextField( focusNode: _emailFocus, // ...其他参数 ) // 点击时手动请求焦点 GestureDetector( onTap: () { FocusScope.of(context).requestFocus(_emailFocus); }, child: CustomTextField( focusNode: _emailFocus, // ...其他参数 ), )
页面销毁时记得释放焦点节点:
@override void dispose() { _emailFocus.dispose(); _passwordFocus.dispose(); super.dispose(); }
3. 检查Scaffold的resizeToAvoidBottomInset设置
若resizeToAvoidBottomInset设为false,键盘弹出时页面不调整布局可能导致焦点丢失:
Scaffold( resizeToAvoidBottomInset: true, // 确保此项为true // ...其他内容 )
4. 确认GetX控制器是否重复初始化
若页面中多次调用Get.put(SigninController()),会导致TextEditingController被重建,丢失焦点:
- 确保控制器只初始化一次,后续用
Get.find获取实例:
final controller = Get.find<SigninController>();
5. 排查全局焦点拦截逻辑
检查项目中是否有全局WidgetsBindingObserver或第三方库拦截焦点事件,导致键盘弹出后焦点被强制移除。
内容的提问来源于stack exchange,提问作者Anderson André
相关产品推荐
相关产品推荐

