You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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浏览器

可能原因

  1. 手动嵌套Semantics组件与TextFormField自身的无障碍语义冲突,导致VoiceOver识别的焦点和实际输入焦点不一致
  2. Flutter 3.7.x版本在Web端对VoiceOver的焦点处理存在已知兼容性问题
  3. 焦点节点(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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 03:36:30