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

Flutter TextFormField唤起日期选择器重复弹出无法关闭的焦点问题问询

问题根因

  • 当前的onFocusChange回调没有判断焦点状态,无论是获得焦点还是失去焦点都会触发日期选择器的弹出逻辑。当你选中日期后调用unfocus,焦点状态再次变化,就会二次触发弹窗逻辑,导致选择器反复弹出。
  • 另外TextFormField默认处于可编辑状态,更新输入框内容时也可能触发焦点重新获取,进一步复现问题。

解决方案

核心修改点有3个:

  1. 在onFocusChange中增加判断,只有当focus == true(即输入框获得焦点)时才弹出日期选择器
  2. 给TextFormField增加readOnly: true属性,禁止手动输入、避免软键盘弹出,同时阻断内容更新时的焦点异常触发
  3. 移除不必要的FocusScope嵌套,简化层级

修正后代码如下:

Container(
  width: Width * 0.45,
  child: Focus(
    onFocusChange: (focus) async {
      // 仅在获得焦点时触发弹窗
      if (!focus) return;
      DateTime selectedDate = DateTime.now();

      final DateTime? picked = await showDatePicker(
        context: context,
        initialDate: selectedDate,
        firstDate: DateTime(1900, 1),
        lastDate: DateTime(2022)
      );
      if (picked != null && picked != selectedDate) {
        setState(() {
          bookDate.text = DateFormat("yyyy-MM-d").format(picked).toString();
        });
      }
      // 选中后直接失焦
      FocusScope.of(context).unfocus();
    },
    child: TextFormField(
      controller: bookDate,
      // 关键:设置为只读,避免手动输入和异常焦点触发
      readOnly: true,
      decoration: InputDecoration(
        suffixIcon: IconButton(
          onPressed: () async {},
          icon: Icon(
            Icons.date_range_outlined,
            color: Color(0xffbdbdbd),
          ),
        ),
        labelText: "Date",
        labelStyle: TextStyle(
          color: textGreyColor,
          fontFamily: 'SegoeUI'
        ),
        fillColor: Colors.white,
        focusedBorder: OutlineInputBorder(
          borderSide: BorderSide(color: kPrimaryColor, width: 1.0),
        ),
        enabledBorder: OutlineInputBorder(
          borderSide: BorderSide(color: Color(0xffE6E6E6), width: 1.0),
        ),
        border: OutlineInputBorder(
          borderRadius: BorderRadius.circular(10),
          borderSide: BorderSide(color: Color(0xffE6E6E6)),
        ),
      ),
      style: TextStyle(
        fontFamily: "SegoeUI",
        color: kPrimaryColor
      ),
    ),
  ),
),

如果想要更简单的实现,也可以不用监听焦点,直接给TextFormField套一层GestureDetector,监听onTap事件弹出选择器,逻辑更直观,也不会有焦点异常问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 06:30:00