Flutter Web下TextFormField搭配VoiceOver存在焦点异常问题
Flutter Web + VoiceOver:TextFormField焦点错位、输入无响应问题
问题描述
在Flutter Web环境下使用VoiceOver时,TextFormField存在焦点不稳定问题:无障碍焦点切换到第二个输入框后,输入光标仍停留在第一个;VoiceOver提示已进入文本字段,但输入框经常无法响应输入,焦点随机获取/丢失。
复现步骤
- 开启VoiceOver,使用
Ctrl + Option + 右箭头导航至TextFormField - 继续导航至第2、3、4个TextFormField
- VoiceOver提示“您处于文本字段中,可输入内容”,但获焦输入框常无法响应输入
- 问题表现不稳定,TextFormField随机获取/失去焦点
该问题可在Flutter Gallery的TextField示例中复现。
环境信息
- Flutter 稳定版3.7.0,运行于macOS 12.5
- Android SDK 33.0.0、Xcode 14.1、Chrome浏览器
可能原因
- 手动嵌套
Semantics组件与TextFormField自身的无障碍语义冲突,导致VoiceOver识别的焦点和实际输入焦点不一致 - Flutter 3.7.x版本在Web端对VoiceOver的焦点处理存在已知兼容性问题
- 焦点节点(FocusNode)的手动管理与无障碍导航的自动焦点切换逻辑冲突
解决方案
1. 移除手动嵌套的Semantics组件
TextFormField内部已默认集成完整的无障碍语义实现,手动添加Semantics会覆盖或干扰原有逻辑,引发焦点错位。调整后代码如下:
TextFormField( autovalidateMode: AutovalidateMode.onUserInteraction, controller: _addressLine2Controller, keyboardType: TextInputType.text, textInputAction: TextInputAction.next, validator: (value) { if (value == null || value.isEmpty) { return 'Please enter some text in line 2'; } return null; }, inputFormatters: [LengthLimitingTextInputFormatter(255)], decoration: const InputDecoration( hintText: 'Address Line 2', labelText: 'Address Line 2', errorBorder: OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(6)), borderSide: BorderSide(color: Colors.red), ) ), focusNode: _addressLine2, onSaved: (value) { _city.requestFocus(); }, ),
2. 升级Flutter到最新稳定版
Flutter后续版本(如3.10+)已修复多个Web端无障碍焦点相关bug,升级后可解决大部分兼容性问题。执行升级命令:
flutter upgrade
3. 优化焦点节点管理逻辑
避免在onSaved中直接调用requestFocus,改用textInputAction配合onFieldSubmitted处理焦点切换,确保无障碍导航与输入焦点同步:
TextFormField( // 保留其他原有属性 textInputAction: TextInputAction.next, focusNode: _addressLine2, onFieldSubmitted: (value) { _city.requestFocus(); }, ),
4. 临时禁用Web端焦点自动管理(Workaround)
在main.dart中添加以下配置,强制Flutter使用原生焦点系统:
void main() { debugDefaultTargetPlatformOverride = TargetPlatform.fuchsia; runApp(const MyApp()); }
注:此为临时方案,仅紧急情况使用,版本升级后建议移除。
内容的提问来源于stack exchange,提问作者md code
相关产品推荐
相关产品推荐

