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

点击CupertinoSegmentedControl时TextField的onFocusChange未触发问题求助

问题解决:点击CupertinoSegmentedControl时TextField的onFocusChange未触发

问题原因

CupertinoSegmentedControl默认不参与焦点系统,点击它不会主动请求焦点,导致TextField的焦点不会被夺走,因此onFocusChange事件不会触发。

两种可行解决方案

方案1:让CupertinoSegmentedControl可请求焦点

给CupertinoSegmentedControl包裹Focus组件,使其能够获取焦点,点击时自动触发TextField的失焦事件:

Column( // task type
  children: [
    Focus(
      child: TextField(
        controller: titleController,
        decoration: createDecoration("Title of task", widget.state.validationData.titleHelper),
      ),
      onFocusChange: (hasFocus) {
        print("TASK TITLE has focus: $hasFocus");
        if (!hasFocus) {
          taskEditBloc.add(TaskEditDataEntered(taskData:
            widget.state.taskData!.copyWith(title: () => titleController.text)));
        }
      },
    ),
    // 用Focus包裹SegmentedControl,允许它请求焦点
    Focus(
      canRequestFocus: true,
      child: CupertinoSegmentedControl(
        children: {
          0: const Text('A'),
          1: const Text('B'),
        },
        groupValue: taskType,
        onValueChanged: (value) {
          taskEditBloc.add(TaskEditDataEntered(taskData:
            widget.state.taskData!.copyWith(taskType: () => value)));
        },
      ),
    ),
  ],
)

方案2:手动触发TextField失焦

在CupertinoSegmentedControl的onValueChanged回调里,主动让TextField失去焦点:

Column( // task type
  children: [
    Focus(
      child: TextField(
        controller: titleController,
        decoration: createDecoration("Title of task", widget.state.validationData.titleHelper),
      ),
      onFocusChange: (hasFocus) {
        print("TASK TITLE has focus: $hasFocus");
        if (!hasFocus) {
          taskEditBloc.add(TaskEditDataEntered(taskData:
            widget.state.taskData!.copyWith(title: () => titleController.text)));
        }
      },
    ),
    CupertinoSegmentedControl(
      children: {
        0: const Text('A'),
        1: const Text('B'),
      },
      groupValue: taskType,
      onValueChanged: (value) {
        // 主动让TextField失焦
        titleController.unfocus();
        // 或者使用FocusScope全局失焦:FocusScope.of(context).unfocus();
        taskEditBloc.add(TaskEditDataEntered(taskData:
          widget.state.taskData!.copyWith(taskType: () => value)));
      },
    ),
  ],
)

补充说明

  • 方案1更符合Flutter焦点系统的设计逻辑,自动处理焦点转移;
  • 方案2更直接,适合需要精准控制焦点的场景;
  • 原代码中的定时器可以移除,因为现在onFocusChange会先触发,不需要延迟等待。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 06:15:11