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

Flutter:点击其他组件时如何保持文本输入框的焦点不丢失?

Flutter单选字段选项托盘点击时焦点丢失导致onTap未执行问题

我正在尝试创建一个带选项托盘的单选字段,期望效果:点击选项时,选项托盘保持存在直到onTap执行完成,输入框内容更新后再隐藏。

但当前遇到的问题是:点击选项时,parentFocusNode会失去焦点,导致选项托盘在onTap()回调执行前就被销毁,最终onTap()没有被执行。

组件结构

Overlay选项托盘部分

OverlayEntry(
  child: Focus(
    parentNode: parentFocusNode,
    child: Card(child: ListView()), // 选项列表
  )
)

主输入组件部分

Focus(
  focusNode: parentFocusNode,
  child: TextField(),
)

选项托盘显示/隐藏逻辑

parentFocusNode.addListener(() {
  if (parentNode.hasFocus) showOptions();
  else hideOptions();
});

完整组件代码

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

  @override
  State<SingleSelect> createState() => _SingleSelectState();
}

class _SingleSelectState extends State<SingleSelect> {
  var options = ['option1', 'option2'];
  FocusNode parentFocusNode = FocusNode();
  TextEditingController textFieldController = TextEditingController();
  OverlayEntry? optionsTray;

  void showOptions() {
    optionsTray = OverlayEntry(
      builder: (context) {
        return Positioned(
          top: 50,
          height: 100,
          width: 200,
          child: Focus(
            parentNode: parentFocusNode,
            child: Card(
              child: ListView.builder(
                itemCount: 2,
                itemBuilder: (context, index) => ListTile(
                  title: Text(options[index]),
                  onTap: () => textFieldController.text = options[index],
                ),
              ),
            ),
          ),
        );
      },
    );
    Overlay.of(context).insert(optionsTray!);
  }

  void hideOptions() {
    optionsTray!.remove();
    optionsTray = null;
  }

  @override
  void initState() {
    super.initState();
    parentFocusNode.addListener(() {
      if (parentFocusNode.hasFocus) {
        showOptions();
      } else {
        hideOptions();
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Focus(
      focusNode: parentFocusNode,
      child: TextField(controller: textFieldController),
    );
  }
}

我尝试将Overlay加入同一焦点树,把主组件的Focus.focusNode作为Overlay的Focus.parentNode传入,但点击选项时parentFocusNode仍会失去焦点。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 13:17:46