Flutter Web:点击键盘Done按钮后TextField未失焦问题求助
解决Flutter Web(v3.24+)Safari中TextField双Done按钮问题
这是Flutter v3.24及以上版本的已知Bug:在Safari环境下,TextField弹出键盘时会显示两个Done按钮,行为存在差异:
- 第一个Done按钮:仅隐藏键盘,TextField保持聚焦状态,且不会触发
onSubmitted()和onEditingComplete()方法 - 第二个Done按钮:隐藏键盘的同时让TextField失去聚焦,正常触发对应回调
以下是可行的解决/规避方案:
方案1:隐藏浏览器原生Done按钮(推荐)
第一个Done按钮是Safari为输入框添加的原生控件,可通过注入CSS隐藏它,只保留Flutter渲染的按钮。
在项目的web/index.html的<head>标签内添加以下CSS代码:
<style> /* 隐藏Safari原生输入框的操作栏(包含Done按钮) */ input[type="text"]::-webkit-textfield-decoration-container, input[type="email"]::-webkit-textfield-decoration-container, input[type="password"]::-webkit-textfield-decoration-container { display: none; } </style>
该代码会直接移除Safari为输入框附加的原生装饰容器,彻底消除双按钮问题。
方案2:逻辑层面兼容处理
如果不想修改Web端CSS,可通过FocusNode监听聚焦状态,手动补全第一个Done按钮缺失的逻辑:
class MainApp extends StatefulWidget { const MainApp({super.key}); @override State<MainApp> createState() => _MainAppState(); } class _MainAppState extends State<MainApp> { late FocusNode _focusNode; final TextEditingController _controller = TextEditingController(); @override void initState() { super.initState(); _focusNode = FocusNode(); _focusNode.addListener(_handleFocusChange); } void _handleFocusChange() { // 若TextField失去焦点,手动触发提交逻辑 if (!_focusNode.hasFocus) { _submitContent(_controller.text); } } void _submitContent(String content) { // 这里替换为你的提交逻辑 print("提交内容:$content"); } @override void dispose() { _focusNode.dispose(); _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: Center( child: TextField( focusNode: _focusNode, controller: _controller, decoration: const InputDecoration( hintText: 'Enter your name', ), onSubmitted: _submitContent, onEditingComplete: () { _focusNode.unfocus(); _submitContent(_controller.text); }, ), ), ), ); } }
通过监听聚焦状态,确保无论点击哪个Done按钮,最终都能触发提交逻辑并让TextField正确失焦。
内容的提问来源于stack exchange,提问作者Ben the Border
相关产品推荐
相关产品推荐

