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

Flutter中requestFocus()在Android模拟器生效,Web端Chrome无响应问题

Flutter Web端焦点切换失效问题解决(Android正常,Chrome异常)

你的代码在Android模拟器中能通过「Move focus」按钮正常切换两个输入框的焦点,但在Chrome Web端焦点始终停留在input 1,核心问题出在FocusScopeNode的缓存方式和Web端焦点管理的特性差异上。

问题根源

  1. 你通过fcn ??= FocusScope.of(context)缓存了FocusScopeNode,但Web端的FocusScope在组件状态变化时可能会更新,缓存的节点会失效,导致后续焦点请求无法生效。
  2. 直接对比fcn?.focusedChild的方式在Web端无法准确获取当前焦点状态,和原生平台的焦点判断逻辑存在差异。

修正后的代码

class FocusTestRoute extends StatefulWidget {
  const FocusTestRoute({super.key});

  @override
  State<FocusTestRoute> createState() => _FocusTestRouteState();
}

class _FocusTestRouteState extends State<FocusTestRoute> {
  late FocusNode fn1;
  late FocusNode fn2;

  @override
  void initState() {
    super.initState();
    fn1 = FocusNode();
    fn2 = FocusNode();
    // 初始化后手动请求input1焦点,替代autofocus避免Web端状态不一致
    WidgetsBinding.instance.addPostFrameCallback((_) {
      fn1.requestFocus();
    });
  }

  @override
  void dispose() {
    fn1.dispose();
    fn2.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: Column(
        children: <Widget>[
          TextField(
            focusNode: fn1,
            decoration: const InputDecoration(
              labelText: "input 1",
            ),
          ),
          TextField(
            focusNode: fn2,
            decoration: const InputDecoration(
              labelText: "input 2",
            ),
          ),
          const SizedBox(height: 30),
          ElevatedButton(
            onPressed: () {
              // 每次点击都获取当前有效的FocusScopeNode
              final focusScope = FocusScope.of(context);
              // 通过FocusNode的hasFocus属性判断焦点,Web端更可靠
              if (fn1.hasFocus) {
                focusScope.requestFocus(fn2);
              } else {
                focusScope.requestFocus(fn1);
              }
            },
            child: const Text('Move focus'),
          ),
        ],
      ),
    );
  }
}

关键修改说明

  • 移除了缓存的FocusScopeNode,每次点击按钮时实时获取当前的FocusScope.of(context),确保使用的是有效节点。
  • 改用FocusNode.hasFocus判断焦点状态,这个属性在Web端和原生平台的表现一致,能准确反映当前输入框是否获得焦点。
  • 把autofocus: true替换为initState中手动请求焦点,避免Web端自动聚焦可能引发的状态不同步问题。
  • 完善了FocusNode的生命周期管理,在组件销毁时释放资源,防止内存泄漏。

内容的提问来源于stack exchange,提问作者Pauli

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 12:33:28