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

如何实现初始显示TextField,点击后弹出CustomCalendar组件?

实现点击TextField弹出CustomCalendar的方案

直接通过TextField的点击事件触发弹窗,将你的CustomCalendar放入底部弹窗或对话框中,选中日期后更新TextField内容即可,核心实现逻辑如下:

完整代码示例

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

  @override
  State<DatePickerPage> createState() => _DatePickerPageState();
}

class _DatePickerPageState extends State<DatePickerPage> {
  final TextEditingController _dateInputController = TextEditingController();

  @override
  void dispose() {
    _dateInputController.dispose();
    super.dispose();
  }

  void _openCalendarModal() {
    showModalBottomSheet(
      context: context,
      isScrollControlled: true,
      builder: (ctx) => SizedBox(
        height: MediaQuery.of(ctx).size.height * 0.6,
        child: CustomCalendar(
          earliestDate: DateTime.now().subtract(const Duration(days: 120 * 365)),
          latestDate: DateTime.now().subtract(const Duration(days: 18 * 365)),
          validationCallBack: (selectedDate) {
            if (selectedDate != null) {
              // 更新TextField显示的日期文本
              setState(() {
                _dateInputController.text = "${selectedDate.year}-${selectedDate.month}-${selectedDate.day}";
              });
              // 保留你原有的Bloc状态更新逻辑
              BlocProvider.of<FormValidationBloc<KnowMoreValidationResult>>(context)
                  .add(FieldUpdatedEvent(
                fieldName: formDefinition.dobField,
                value: selectedDate.toIso8601String(),
              ));
              // 选中日期后关闭弹窗
              Navigator.pop(ctx);
            }
            return null;
          },
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 16),
        child: TextField(
          controller: _dateInputController,
          readOnly: true, // 设置只读,避免触发系统键盘
          onTap: _openCalendarModal,
          decoration: const InputDecoration(
            labelText: "选择出生日期",
            suffixIcon: Icon(Icons.calendar_month),
            border: OutlineInputBorder(),
          ),
        ),
      ),
    );
  }
}

关键注意点

  • 将TextField设为readOnly: true,确保点击时只触发我们的弹窗逻辑,不会弹出系统键盘。
  • 用showModalBottomSheet承载日历组件,通过isScrollControlled和SizedBox调整弹窗高度,适配日历的显示需求。
  • 在日历的回调方法中,完成TextField文本更新、Bloc状态提交后,手动关闭弹窗。

如果你的CustomCalendar提供了专门的日期选中回调(而非validationCallBack),可以直接替换成对应回调来处理日期选中逻辑,代码结构保持一致即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 15:22:48