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

Flutter Web在Android与iOS平台的焦点行为差异问题排查

iOS浏览器中TextFieldTapRegion失效导致TextField失焦的原因分析

问题场景

我开发了一个简单的Flutter Web应用,布局使用Row组件,包含一个TextField和一个被TextFieldTapRegion包裹的ElevatedButton。选中TextField时光标闪烁、边框激活,符合预期。但点击按钮时出现跨平台差异:

  • 在PC(Chrome)和Android(Chrome)上,点击按钮不会影响TextField的焦点状态,符合TextFieldTapRegion的预期作用;
  • 在iOS的Safari和Chrome浏览器中,点击按钮会导致TextField失去焦点。

复现代码

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Row(
        children: <Widget>[
          Expanded(
            child: MyInputField(),
          ),
          Expanded(
            child: TextFieldTapRegion(
              child: ElevatedButton(
                onPressed: () {},
                child: Text("A button"),
              ),
            ),
          ),
        ],
      ),
    );
  }
}


class MyInputField extends StatelessWidget {
  final TextEditingController controller = TextEditingController();

  FocusNode focusNode = FocusNode();

  MyInputField({Key? key}) : super(key: key) {
    focusNode.requestFocus();
  }
  
  @override
  Widget build(BuildContext context) {
    return Focus(
      autofocus: true,
      child: TextField(
        controller: controller,
        textAlign: TextAlign.center,
        autofocus: true,
        textInputAction: TextInputAction.none,
        showCursor: true,
        enabled: true,
        focusNode: focusNode,
        keyboardType:TextInputType.none, //no system keyboard
      ),
    );
  }
}

核心原因

1. iOS WebKit内核的原生焦点行为限制

iOS的Safari和Chrome浏览器都基于WebKit内核,该内核在处理点击事件时有一个原生逻辑:无论元素是否需要焦点,点击后都会尝试将焦点转移到触发点击的元素。这种行为优先级高于Flutter Web的事件拦截逻辑,导致TextFieldTapRegion的防失焦规则被原生行为覆盖,点击按钮时TextField的焦点被强制夺走。

2. Flutter Web的平台适配差异

TextFieldTapRegion的实现依赖于不同平台的事件处理机制:

  • 在桌面端(PC Chrome)和Android浏览器中,Flutter可以直接拦截事件冒泡,阻止焦点转移操作,因此能正常保留TextField的焦点;
  • 但在iOS浏览器中,WebKit的焦点管理属于原生层逻辑,Flutter的事件拦截无法完全覆盖,导致TextFieldTapRegion的功能失效。

额外影响因素

代码中MyInputField同时使用了Focus.autofocus、TextField.autofocus,并在构造函数中调用focusNode.requestFocus(),多重焦点请求会导致iOS平台上的焦点状态不稳定,进一步加剧了被原生行为干扰的概率。

内容的提问来源于stack exchange,提问作者Marc Van Daele

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 15:28:10