Flutter中如何让TextField保持聚焦状态,同时完全隐藏软键盘与光标
我之前做过好几次硬件条码扫描器的对接需求,你的思路是对的——用一个隐藏的TextField接收模拟键盘输入,只需要几个关键调整就能解决软键盘弹出的问题,同时完全保留扫描输入的能力:
核心修改点
1. 用TextInputType.none阻止软键盘弹出
这是最关键的一步:把TextField的keyboardType设置为TextInputType.none,这个类型会告诉系统不要唤起软键盘,但依然会保留硬件模拟键盘的输入通道(扫描器本质就是模拟快速敲击键盘的硬件,完全不受影响)。
2. 彻底隐藏光标
添加showCursor: false、cursorWidth: 0或cursorColor: Colors.transparent,确保光标完全不可见,避免在极小的隐藏区域里还有残留的光标显示。
3. 强化焦点保持(可选但推荐)
监听FocusNode的失焦事件,自动重新请求焦点,防止页面中其他控件意外抢走焦点导致扫描输入失效。
修改后的HiddenTextField代码
class HiddenTextField extends StatelessWidget { final TextEditingController controller; final FocusNode focusNode; final void Function(String)? onSubmitted; const HiddenTextField({ super.key, required this.controller, required this.focusNode, this.onSubmitted, }); @override Widget build(BuildContext context) { // 可选:监听焦点,失焦自动重新请求,确保始终能接收扫描输入 focusNode.addListener(() { if (!focusNode.hasFocus) { Future.microtask(() => focusNode.requestFocus()); } }); return Material( type: MaterialType.transparency, child: SizedBox.shrink( // 用shrink替代1x1盒子更简洁 child: Opacity( opacity: 0, child: TextField( controller: controller, focusNode: focusNode, autofocus: true, enableSuggestions: false, autocorrect: false, enableIMEPersonalizedLearning: false, // 关键1:阻止软键盘弹出,保留硬件输入通道 keyboardType: TextInputType.none, // 关键2:彻底隐藏光标 showCursor: false, cursorWidth: 0, cursorColor: Colors.transparent, // 禁用文本选择,防止意外触发交互 enableInteractiveSelection: false, onSubmitted: onSubmitted, ), ), ), ); } }
使用时的注意事项
焦点管理:
你的SummingSessionState里用Future.delayed请求焦点的方式很稳妥,结合上面的焦点监听,双重保险确保始终聚焦。注意一定要在dispose中正确销毁FocusNode和TextEditingController,你的代码已经做了这一步,非常规范。扫描输入的延迟处理:
你用Timer延迟250ms处理条码输入的逻辑非常正确——扫描器会快速连续输入字符,短延迟能确保我们拿到完整的条码内容再处理,避免截断。可以根据扫描器的速度微调这个延迟(150-300ms区间都适用)。为什么不能用
readOnly: true:readOnly会直接关闭TextField的输入通道,不仅软键盘弹不出来,硬件模拟的键盘输入也会被阻断,这就是你设置readOnly后接收不到扫描数据的核心原因,绝对不能用这个属性。
额外优化建议
如果你的应用需要在多页面切换时保持扫描能力,可以把HiddenTextField放在全局Overlay中,或者用状态管理工具(比如Provider、GetX)管理全局的FocusNode和TextEditingController,避免页面切换时丢失焦点。
这样修改后,打开页面时软键盘就不会弹出了,扫描器的输入能正常被TextEditingController接收,光标也完全不可见,完全符合你的需求!




