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

Flutter待办APP自定义提醒弹窗实现方案咨询

实现自定义Todo提醒弹窗的分步指导

1. 搭建弹窗基础结构

用Flutter原生的showModalBottomSheet实现底部弹窗(更贴合移动端交互习惯),基础框架如下:

typedef ReminderCallback = void Function(DateTime? reminderTime, RepeatType repeatType);

void showReminderModal(BuildContext context, ReminderCallback onConfirm) {
  showModalBottomSheet(
    context: context,
    isScrollControlled: true,
    shape: const RoundedRectangleBorder(
      borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
    ),
    builder: (context) => StatefulBuilder(
      builder: (context, setState) {
        DateTime? selectedDateTime;
        RepeatType selectedRepeat = RepeatType.none;
        
        return Padding(
          padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
          child: SingleChildScrollView(
            padding: const EdgeInsets.all(16),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                const Text("设置提醒", style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
                // 后续添加时间选择、重复选项、操作按钮
              ],
            ),
          ),
        );
      },
    ),
  );
}

// 定义重复类型枚举
enum RepeatType { none, daily, weekly, monthly, yearly }

2. 实现特定时间选择功能

组合原生showDatePicker和showTimePicker,让用户选择日期+时间,用intl包格式化时间显示(需在pubspec.yaml添加intl: ^0.18.1):

// 在Column的children中添加时间选择ListTile
const SizedBox(height: 16),
ListTile(
  title: Text(selectedDateTime != null 
      ? DateFormat("yyyy-MM-dd HH:mm").format(selectedDateTime) 
      : "选择提醒时间"),
  trailing: const Icon(Icons.arrow_forward_ios),
  onTap: () async {
    final date = await showDatePicker(
      context: context,
      initialDate: DateTime.now(),
      firstDate: DateTime.now(),
      lastDate: DateTime.now().add(const Duration(days: 365)),
    );
    if (date != null) {
      final time = await showTimePicker(
        context: context,
        initialTime: TimeOfDay.fromDateTime(DateTime.now()),
      );
      if (time != null) {
        setState(() {
          selectedDateTime = DateTime(
            date.year, date.month, date.day,
            time.hour, time.minute,
          );
        });
      }
    }
  },
),

3. 实现重复提醒选项

用RadioListTile实现「不重复/每天/每周/每月/每年」的单选选项:

// 在时间选择组件后添加重复选项区域
const SizedBox(height: 16),
const Text("重复提醒", style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500)),
RadioListTile<RepeatType>(
  title: const Text("不重复"),
  value: RepeatType.none,
  groupValue: selectedRepeat,
  onChanged: (value) => setState(() => selectedRepeat = value!),
),
RadioListTile<RepeatType>(
  title: const Text("每天"),
  value: RepeatType.daily,
  groupValue: selectedRepeat,
  onChanged: (value) => setState(() => selectedRepeat = value!),
),
RadioListTile<RepeatType>(
  title: const Text("每周"),
  value: RepeatType.weekly,
  groupValue: selectedRepeat,
  onChanged: (value) => setState(() => selectedRepeat = value!),
),
RadioListTile<RepeatType>(
  title: const Text("每月"),
  value: RepeatType.monthly,
  groupValue: selectedRepeat,
  onChanged: (value) => setState(() => selectedRepeat = value!),
),
RadioListTile<RepeatType>(
  title: const Text("每年"),
  value: RepeatType.yearly,
  groupValue: selectedRepeat,
  onChanged: (value) => setState(() => selectedRepeat = value!),
),

4. 添加确认/取消按钮

在弹窗底部添加操作按钮,点击确认时将选择结果通过回调返回给父组件:

// 在重复选项区域后添加按钮行
const SizedBox(height: 24),
Row(
  mainAxisAlignment: MainAxisAlignment.end,
  children: [
    TextButton(
      onPressed: () => Navigator.pop(context),
      child: const Text("取消"),
    ),
    const SizedBox(width: 8),
    ElevatedButton(
      onPressed: () {
        onConfirm(selectedDateTime, selectedRepeat);
        Navigator.pop(context);
      },
      child: const Text("确认"),
    ),
  ],
),

5. 整合到Todo应用

在你的Todo添加/编辑页面中调用弹窗:

ElevatedButton(
  onPressed: () {
    showReminderModal(context, (reminderTime, repeatType) {
      // 这里将提醒设置保存到你的Todo数据模型中
      // 示例:todo.reminderTime = reminderTime;
      // todo.repeatType = repeatType;
    });
  },
  child: const Text("设置提醒"),
),

可选优化

  • 若需要更美观的滚轮式时间选择,可替换为CupertinoDatePicker实现iOS风格交互;
  • 针对「每周重复」可扩展多选星期几的功能;
  • 当Todo已有提醒时,弹窗默认填充已有设置,添加「清除提醒」选项;
  • 处理时区问题,确保提醒时间在不同时区下的准确性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 19:23:11