Flutter TextFormField焦点异常:点击发送后键盘无法重复唤起
解决Flutter点击发送按钮后键盘无法重复唤起的问题
问题背景
需求:点击发送按钮时保持键盘处于打开/聚焦状态,不关闭。
当前问题:首次点击发送按钮时,键盘关闭后通过focusNode.requestFocus()能重新唤起,但再次点击后键盘无法打开。经追踪发现,第二次调用时焦点管理器中以下条件始终为true,导致代码直接返回,未尝试唤起键盘:
if (hasPrimaryFocus && (_manager!._markedForFocus == null || _manager!._markedForFocus == this)) {
尽管键盘已关闭,但焦点节点仍被标记为拥有主焦点,无法触发重新聚焦逻辑。
解决方案1(最优):点击发送按钮时不让键盘关闭
核心思路:避免主动隐藏键盘,同时确保发送操作不会夺走输入框的焦点。
修改UI代码
移除SystemChannels.textInput.invokeMethod('TextInput.hide'),并给按钮添加跳过焦点遍历的配置,防止抢占输入框焦点:
return Form( key: _formKey, child: Row( children: <Widget>[ Expanded( child: TextFormField( focusNode: chatController.focusNode, // 可选:设置回车触发发送,提升交互体验 textInputAction: TextInputAction.send, onFieldSubmitted: (_) async { if (_formKey.currentState!.validate()) { await chatController.sendMessage(context); } }, ), ), IconButton( // 跳过焦点遍历,防止按钮抢占输入框焦点 focusNode: FocusNode(skipTraversal: true), icon: const Icon(Icons.send), onPressed: () async { // 移除主动隐藏键盘的代码 if (_formKey.currentState!.validate()) { await chatController.sendMessage(context); } }, ), ], ), );
修改控制器代码
无需额外处理焦点,发送逻辑执行完成后输入框会自动保持焦点:
late FocusNode focusNode; @override void onReady() { focusNode = FocusNode(); super.onReady(); } void sendMessage(BuildContext context) async { // 执行你的消息发送逻辑 // ... // 若有清空输入框操作,无需额外调用requestFocus,焦点仍会保留 // textEditingController.clear(); }
解决方案2(可行):确保每次点击都能唤起键盘
如果业务需要先隐藏键盘再唤起(比如清空输入框后重新聚焦),可以通过先强制取消焦点,再延迟请求焦点的方式绕过焦点管理器的判断逻辑。
修改控制器代码
late FocusNode focusNode; @override void onReady() { focusNode = FocusNode(); super.onReady(); } void sendMessage(BuildContext context) async { // 1. 强制取消焦点,标记节点为失焦状态 focusNode.unfocus(); // 2. 短暂延迟,确保焦点状态完成更新 await Future.delayed(const Duration(milliseconds: 100)); // 3. 重新请求焦点,唤起键盘 focusNode.requestFocus(); // 执行你的消息发送逻辑 // ... }
修改UI代码
可选择保留或移除TextInput.hide,上述逻辑会强制重新唤起键盘:
IconButton( icon: const Icon(Icons.send), onPressed: () async { // 可选:如果需要先隐藏键盘再唤起 // SystemChannels.textInput.invokeMethod('TextInput.hide'); if (_formKey.currentState!.validate()) { await chatController.sendMessage(context); } }, ),
内容的提问来源于stack exchange,提问作者Navnav
相关产品推荐
相关产品推荐

