反向闹钟应用


欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net

一、项目概述

运行效果图
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.1 应用简介

反向闹钟是一款创新的睡眠健康管理应用,与传统闹钟不同,它的核心功能是提醒用户该睡觉了,而非叫醒用户。通过科学的作息管理和温和的睡前提醒,帮助用户建立健康的睡眠习惯,改善睡眠质量。

现代生活节奏快,很多人习惯熬夜,传统闹钟只能叫醒你,却无法帮助你早睡。反向闹钟填补了这一空白,通过设定目标睡觉时间,在睡前适时提醒用户放下手机、准备入睡,从根本上改善睡眠质量。

1.2 核心功能

功能模块 功能描述 实现方式
睡前倒计时 实时显示距离睡觉时间还有多久 动态计算当前时间与目标睡觉时间的差值
作息设置 设置睡觉和起床时间 TimePicker 时间选择器
提醒模式 四种提醒强度可选 ChoiceChip 模式选择
睡眠记录 记录实际入睡和起床时间 日期时间选择器组合
睡眠统计 分析睡眠质量和准时率 数据可视化图表
睡眠小贴士 每日推送睡眠健康建议 循环数组展示

1.3 提醒模式

序号 模式名称 图标 颜色 说明
1 温和提醒 notifications_none 绿色 #10B981 轻柔提示,不打扰
2 普通提醒 notifications 紫色 #6366F1 标准提醒通知
3 严格模式 notifications_active 橙色 #F59E0B 频繁提醒,确保注意
4 强制模式 lock_clock 红色 #EF4444 强制锁屏,必须睡觉

1.4 技术栈

技术领域 技术选型 版本要求
开发框架 Flutter >= 3.0.0
编程语言 Dart >= 2.17.0
设计规范 Material Design 3 -
状态管理 setState -
时间处理 intl -
目标平台 鸿蒙OS / Android / iOS API 21+

1.5 项目结构

lib/
└── main_reverse_alarm.dart
    ├── ReverseAlarmApp        # 应用入口
    ├── BedtimeReminderMode    # 提醒模式枚举
    ├── SleepQuality           # 睡眠质量枚举
    ├── SleepSchedule          # 作息计划模型
    ├── SleepRecord            # 睡眠记录模型
    ├── ReverseAlarmHomePage   # 主页面(底部导航)
    ├── _buildHomePage         # 首页(倒计时)
    ├── _buildSchedulePage     # 作息设置页面
    ├── _buildStatisticsPage   # 统计页面
    └── _buildSettingsPage     # 设置页面

二、系统架构

2.1 整体架构图

Data Layer

Presentation Layer

主页面
ReverseAlarmHomePage

首页

作息设置

睡眠统计

设置

倒计时卡片

作息概览

快捷操作

睡眠贴士

时间设置

提醒模式

重复日期

数据概览

质量分布

最近记录

SleepSchedule
作息计划

SleepRecord
睡眠记录

BedtimeReminderMode
提醒模式

SleepQuality
睡眠质量

2.2 类图设计

manages

manages

uses

uses

has

ReverseAlarmApp

+Widget build()

«enumeration»

BedtimeReminderMode

+String label

+IconData icon

+Color color

+gentle

+normal

+strict

+force

«enumeration»

SleepQuality

+String label

+int value

+Color color

+excellent

+good

+average

+poor

+terrible

SleepSchedule

+TimeOfDay bedtime

+TimeOfDay wakeTime

+List<int> repeatDays

+bool isEnabled

+Duration sleepDuration

+String sleepDurationText

SleepRecord

+String id

+DateTime date

+DateTime actualBedtime

+DateTime actualWakeTime

+SleepQuality quality

+String note

+Duration actualSleepDuration

ReverseAlarmHomePage

-int _selectedIndex

-SleepSchedule _schedule

-BedtimeReminderMode _reminderMode

-int _reminderMinutesBefore

-bool _isReminderEnabled

-List<SleepRecord> _sleepRecords

+Widget build()

-Widget _buildHomePage()

-Widget _buildSchedulePage()

-Widget _buildStatisticsPage()

-Widget _buildSettingsPage()

2.3 页面导航流程

首页

作息

统计

设置

应用启动

主页面

底部导航

首页展示

作息设置页面

睡眠统计页面

设置页面

点击记录睡眠

记录睡眠弹窗

选择时间质量

保存记录

点击调整作息

设置睡觉时间

设置起床时间

选择提醒模式

选择重复日期

查看统计数据

查看质量分布

查看最近记录

2.4 数据流向图

数据模型 统计页 作息页 首页 用户 数据模型 统计页 作息页 首页 用户 打开应用 获取作息时间 返回SleepSchedule 显示倒计时 进入作息设置 获取当前设置 修改睡觉时间 更新SleepSchedule 通知更新 刷新倒计时 记录睡眠 创建SleepRecord 同步数据 更新统计图表

三、核心模块设计

3.1 数据模型设计

3.1.1 提醒模式枚举 (BedtimeReminderMode)
enum BedtimeReminderMode {
  gentle('温和提醒', Icons.notifications_none, Color(0xFF10B981)),
  normal('普通提醒', Icons.notifications, Color(0xFF6366F1)),
  strict('严格模式', Icons.notifications_active, Color(0xFFF59E0B)),
  force('强制模式', Icons.lock_clock, Color(0xFFEF4444));

  final String label;
  final IconData icon;
  final Color color;
  
  const BedtimeReminderMode(this.label, this.icon, this.color);
}
3.1.2 睡眠质量枚举 (SleepQuality)
enum SleepQuality {
  excellent('非常好', 5, Color(0xFF10B981)),
  good('好', 4, Color(0xFF6366F1)),
  average('一般', 3, Color(0xFFF59E0B)),
  poor('较差', 2, Color(0xFFF97316)),
  terrible('很差', 1, Color(0xFFEF4444));

  final String label;
  final int value;
  final Color color;
  
  const SleepQuality(this.label, this.value, this.color);
}
3.1.3 作息计划模型 (SleepSchedule)
class SleepSchedule {
  final TimeOfDay bedtime;
  final TimeOfDay wakeTime;
  final List<int> repeatDays;
  final bool isEnabled;

  const SleepSchedule({
    required this.bedtime,
    required this.wakeTime,
    this.repeatDays = const [1, 2, 3, 4, 5, 6, 7],
    this.isEnabled = true,
  });

  Duration get sleepDuration {
    var bedtimeMinutes = bedtime.hour * 60 + bedtime.minute;
    var wakeTimeMinutes = wakeTime.hour * 60 + wakeTime.minute;
    if (wakeTimeMinutes < bedtimeMinutes) {
      wakeTimeMinutes += 24 * 60;
    }
    return Duration(minutes: wakeTimeMinutes - bedtimeMinutes);
  }

  String get sleepDurationText {
    final duration = sleepDuration;
    final hours = duration.inHours;
    final minutes = duration.inMinutes % 60;
    if (minutes == 0) {
      return '$hours小时';
    }
    return '$hours小时$minutes分钟';
  }
}
3.1.4 睡眠记录模型 (SleepRecord)
class SleepRecord {
  final String id;
  final DateTime date;
  final DateTime? actualBedtime;
  final DateTime? actualWakeTime;
  final SleepQuality? quality;
  final String? note;

  SleepRecord({
    required this.id,
    required this.date,
    this.actualBedtime,
    this.actualWakeTime,
    this.quality,
    this.note,
  });

  Duration? get actualSleepDuration {
    if (actualBedtime == null || actualWakeTime == null) return null;
    return actualWakeTime!.difference(actualBedtime!);
  }
}

3.2 页面结构图

3.2.1 首页结构

首页
CustomScrollView

SliverAppBar
渐变背景

SliverToBoxAdapter

倒计时卡片

作息设置卡片

快捷操作区

睡眠贴士卡片

状态文字图标

大数字倒计时

提醒模式标签

睡觉时间

起床时间

目标睡眠时长

记录睡眠

调整作息

睡眠分析

3.2.2 作息设置页结构

作息设置页

作息时间卡片

提醒设置卡片

重复日期卡片

睡觉时间选择

起床时间选择

预计睡眠时长

提醒开关

提醒模式选择

提前提醒时间

周一到周日选择

3.2.3 统计页结构

睡眠统计页

数据概览卡片

质量分布图表

最近记录列表

平均睡眠时长

准时率

记录天数

非常好

一般

较差

很差

3.3 倒计时计算逻辑

获取当前时间

计算当前分钟数

计算目标睡觉分钟数

是否已过睡觉时间?

加24小时

计算差值

转换为小时分钟

是否接近睡觉时间?

显示提醒样式

显示普通样式


四、UI设计规范

4.1 配色方案

应用采用紫色为主色调,传递宁静、舒适的睡眠氛围:

颜色类型 色值 用途
主色 #6366F1 (Indigo) 导航、强调元素、睡觉时间
辅色 #8B5CF6 (Purple) 渐变背景、装饰元素
起床色 #F59E0B (Amber) 起床时间、警告提醒
成功色 #10B981 (Emerald) 成功状态、睡眠时长
温和模式 #10B981 (Green) 温和提醒
普通模式 #6366F1 (Indigo) 普通提醒
严格模式 #F59E0B (Orange) 严格提醒
强制模式 #EF4444 (Red) 强制提醒
贴士背景 #FEF3C7 (Warm Yellow) 睡眠小贴士卡片

4.2 字体规范

元素 字号 字重 颜色
倒计时数字 72px Bold #000000
时间单位 18px Regular #000000
状态文字 18px Medium 根据状态变化
卡片标题 18px Bold #000000
时间显示 28px Bold 主题色
按钮文字 13px Regular #000000
小贴士标题 14px Bold #92400E
小贴士内容 13px Regular #A16207

4.3 组件规范

4.3.1 倒计时卡片
┌─────────────────────────────────────────┐
│                                         │
│    ⏰ 睡觉时间快到了                     │
│                                         │
│        14        32                     │
│       小时      分钟                    │
│                                         │
│    ┌─────────────────────────────┐     │
│    │  🔔 普通提醒 · 提前30分钟    │     │
│    └─────────────────────────────┘     │
│                                         │
└─────────────────────────────────────────┘
4.3.2 作息设置卡片
┌─────────────────────────────────────────┐
│  今日作息                          [开关]│
├─────────────────────────────────────────┤
│                                         │
│   🌙 睡觉时间      │      ☀️ 起床时间    │
│     23:00         │        07:00        │
│                                         │
├─────────────────────────────────────────┤
│                                         │
│      🌙 目标睡眠时长: 8小时0分钟         │
│                                         │
└─────────────────────────────────────────┘
4.3.3 快捷操作按钮
┌──────────┐  ┌──────────┐  ┌──────────┐
│    🛏️    │  │   📅     │  │   📊     │
│  记录睡眠 │  │  调整作息 │  │  睡眠分析 │
└──────────┘  └──────────┘  └──────────┘
4.3.4 睡眠小贴士卡片
┌─────────────────────────────────────────┐
│  💡  今日睡眠小贴士                      │
│      睡前1小时避免使用电子设备           │
└─────────────────────────────────────────┘

五、核心功能实现

5.1 睡前倒计时实现

Widget _buildHomePage() {
  final now = DateTime.now();
  final currentTime = TimeOfDay.fromDateTime(now);
  final bedtimeMinutes = _schedule.bedtime.hour * 60 + _schedule.bedtime.minute;
  final currentMinutes = currentTime.hour * 60 + currentTime.minute;

  // 计算剩余分钟数
  var minutesUntilBedtime = bedtimeMinutes - currentMinutes;
  if (minutesUntilBedtime < 0) {
    minutesUntilBedtime += 24 * 60; // 跨天处理
  }

  final hoursUntil = minutesUntilBedtime ~/ 60;
  final minsUntil = minutesUntilBedtime % 60;

  // 判断是否接近睡觉时间
  final isNearBedtime = minutesUntilBedtime <= _reminderMinutesBefore && minutesUntilBedtime > 0;
  final isPastBedtime = currentMinutes > bedtimeMinutes && currentMinutes - bedtimeMinutes < 120;

  return Scaffold(
    body: CustomScrollView(
      slivers: [
        SliverAppBar(
          expandedHeight: 200,
          pinned: true,
          flexibleSpace: FlexibleSpaceBar(
            title: const Text('反向闹钟'),
            background: Container(
              decoration: const BoxDecoration(
                gradient: LinearGradient(
                  begin: Alignment.topLeft,
                  end: Alignment.bottomRight,
                  colors: [Color(0xFF6366F1), Color(0xFF8B5CF6)],
                ),
              ),
            ),
          ),
        ),
        SliverToBoxAdapter(
          child: Padding(
            padding: const EdgeInsets.all(16),
            child: Column(
              children: [
                _buildCountdownCard(hoursUntil, minsUntil, isNearBedtime, isPastBedtime),
                const SizedBox(height: 16),
                _buildSleepScheduleCard(),
                const SizedBox(height: 16),
                _buildQuickActions(),
                const SizedBox(height: 16),
                _buildSleepTipCard(),
              ],
            ),
          ),
        ),
      ],
    ),
  );
}

5.2 倒计时卡片实现

Widget _buildCountdownCard(int hoursUntil, int minsUntil, bool isNearBedtime, bool isPastBedtime) {
  String statusText;
  IconData statusIcon;
  Color statusColor;

  if (isPastBedtime) {
    statusText = '已过睡觉时间';
    statusIcon = Icons.warning;
    statusColor = Colors.orange;
  } else if (isNearBedtime) {
    statusText = '睡觉时间快到了';
    statusIcon = Icons.access_alarm;
    statusColor = _reminderMode.color;
  } else {
    statusText = '距离睡觉时间';
    statusIcon = Icons.schedule;
    statusColor = Theme.of(context).colorScheme.primary;
  }

  return Card(
    elevation: 4,
    child: Container(
      width: double.infinity,
      padding: const EdgeInsets.all(24),
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(12),
        gradient: LinearGradient(
          begin: Alignment.topLeft,
          end: Alignment.bottomRight,
          colors: isNearBedtime
              ? [statusColor.withValues(alpha: 0.2), statusColor.withValues(alpha: 0.1)]
              : [Theme.of(context).colorScheme.surface, Theme.of(context).colorScheme.surface],
        ),
      ),
      child: Column(
        children: [
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Icon(statusIcon, color: statusColor, size: 28),
              const SizedBox(width: 8),
              Text(
                statusText,
                style: TextStyle(fontSize: 18, fontWeight: FontWeight.w500, color: statusColor),
              ),
            ],
          ),
          const SizedBox(height: 16),
          if (!isPastBedtime) ...[
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.end,
              children: [
                Text('$hoursUntil', style: const TextStyle(fontSize: 72, fontWeight: FontWeight.bold, height: 1)),
                const Padding(padding: EdgeInsets.only(bottom: 12), child: Text('小时', style: TextStyle(fontSize: 18))),
                const SizedBox(width: 8),
                Text('$minsUntil', style: const TextStyle(fontSize: 72, fontWeight: FontWeight.bold, height: 1)),
                const Padding(padding: EdgeInsets.only(bottom: 12), child: Text('分钟', style: TextStyle(fontSize: 18))),
              ],
            ),
          ],
          if (_isReminderEnabled && !isPastBedtime) ...[
            Container(
              padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
              decoration: BoxDecoration(
                color: _reminderMode.color.withValues(alpha: 0.1),
                borderRadius: BorderRadius.circular(20),
              ),
              child: Row(
                mainAxisSize: MainAxisSize.min,
                children: [
                  Icon(_reminderMode.icon, size: 16, color: _reminderMode.color),
                  const SizedBox(width: 6),
                  Text('${_reminderMode.label} · 提前$_reminderMinutesBefore分钟', style: TextStyle(fontSize: 13, color: _reminderMode.color)),
                ],
              ),
            ),
          ],
        ],
      ),
    ),
  );
}

5.3 睡眠质量分布图表实现

Widget _buildSleepQualityChart(Map<SleepQuality, int> distribution) {
  final total = distribution.values.fold(0, (a, b) => a + b);

  return Card(
    child: Padding(
      padding: const EdgeInsets.all(16),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          const Text('睡眠质量分布', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
          const SizedBox(height: 16),
          if (total == 0)
            const Center(child: Padding(padding: EdgeInsets.all(32), child: Text('暂无数据', style: TextStyle(color: Colors.grey))))
          else
            Column(
              children: SleepQuality.values.reversed.map((quality) {
                final count = distribution[quality] ?? 0;
                final percentage = total > 0 ? count / total : 0.0;

                return Padding(
                  padding: const EdgeInsets.only(bottom: 12),
                  child: Row(
                    children: [
                      Container(
                        width: 12, height: 12,
                        decoration: BoxDecoration(color: quality.color, borderRadius: BorderRadius.circular(6)),
                      ),
                      const SizedBox(width: 8),
                      SizedBox(width: 60, child: Text(quality.label, style: const TextStyle(fontSize: 13))),
                      Expanded(
                        child: ClipRRect(
                          borderRadius: BorderRadius.circular(4),
                          child: LinearProgressIndicator(
                            value: percentage,
                            backgroundColor: Colors.grey[200],
                            valueColor: AlwaysStoppedAnimation<Color>(quality.color),
                            minHeight: 8,
                          ),
                        ),
                      ),
                      const SizedBox(width: 8),
                      SizedBox(width: 40, child: Text('$count次', style: TextStyle(fontSize: 12, color: Colors.grey[600]), textAlign: TextAlign.right)),
                    ],
                  ),
                );
              }).toList(),
            ),
        ],
      ),
    ),
  );
}

5.4 睡眠记录弹窗实现

void _showRecordSleepDialog() {
  DateTime? selectedBedtime;
  DateTime? selectedWakeTime;
  SleepQuality? selectedQuality;
  final noteController = TextEditingController();

  showModalBottomSheet(
    context: context,
    isScrollControlled: true,
    builder: (context) => StatefulBuilder(
      builder: (context, setModalState) => DraggableScrollableSheet(
        initialChildSize: 0.8,
        maxChildSize: 0.95,
        minChildSize: 0.5,
        expand: false,
        builder: (context, scrollController) => Container(
          padding: const EdgeInsets.all(20),
          child: ListView(
            controller: scrollController,
            children: [
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  const Text('记录睡眠', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
                  IconButton(icon: const Icon(Icons.close), onPressed: () => Navigator.pop(context)),
                ],
              ),
              const SizedBox(height: 20),
              ListTile(
                leading: const Icon(Icons.bedtime, color: Color(0xFF6366F1)),
                title: const Text('实际睡觉时间'),
                subtitle: Text(selectedBedtime != null ? DateFormat('MM月dd日 HH:mm').format(selectedBedtime!) : '点击选择'),
                trailing: const Icon(Icons.chevron_right),
                onTap: () async {
                  final now = DateTime.now();
                  final currentContext = context;
                  final date = await showDatePicker(
                    context: currentContext,
                    initialDate: now,
                    firstDate: now.subtract(const Duration(days: 7)),
                    lastDate: now,
                  );
                  if (date != null && currentContext.mounted) {
                    final time = await showTimePicker(context: currentContext, initialTime: TimeOfDay.fromDateTime(now));
                    if (time != null) {
                      setModalState(() {
                        selectedBedtime = DateTime(date.year, date.month, date.day, time.hour, time.minute);
                      });
                    }
                  }
                },
              ),
              // ... 起床时间选择类似
              const SizedBox(height: 16),
              const Text('睡眠质量'),
              const SizedBox(height: 8),
              Wrap(
                spacing: 8,
                children: SleepQuality.values.map((quality) {
                  final isSelected = selectedQuality == quality;
                  return ChoiceChip(
                    avatar: Icon(Icons.star, size: 16, color: isSelected ? Colors.white : quality.color),
                    label: Text(quality.label),
                    selected: isSelected,
                    selectedColor: quality.color,
                    labelStyle: TextStyle(color: isSelected ? Colors.white : null),
                    onSelected: (selected) {
                      if (selected) setModalState(() => selectedQuality = quality);
                    },
                  );
                }).toList(),
              ),
              const SizedBox(height: 16),
              TextField(
                controller: noteController,
                decoration: const InputDecoration(labelText: '备注(可选)', border: OutlineInputBorder(), prefixIcon: Icon(Icons.note)),
                maxLines: 2,
              ),
              const SizedBox(height: 24),
              FilledButton(
                onPressed: () {
                  if (selectedBedtime != null && selectedWakeTime != null) {
                    final record = SleepRecord(
                      id: DateTime.now().millisecondsSinceEpoch.toString(),
                      date: selectedBedtime!,
                      actualBedtime: selectedBedtime,
                      actualWakeTime: selectedWakeTime,
                      quality: selectedQuality,
                      note: noteController.text.isEmpty ? null : noteController.text,
                    );
                    setState(() => _sleepRecords.insert(0, record));
                    Navigator.pop(context);
                    ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('睡眠记录已保存')));
                  }
                },
                child: const Text('保存记录'),
              ),
            ],
          ),
        ),
      ),
    ),
  );
}

六、数据统计算法

6.1 平均睡眠时长计算

Duration _calculateAverageSleepDuration() {
  final recordsWithDuration = _sleepRecords.where((r) => r.actualSleepDuration != null).toList();
  if (recordsWithDuration.isEmpty) return const Duration(hours: 7);
  
  final totalMinutes = recordsWithDuration.fold<int>(0, (sum, r) => sum + r.actualSleepDuration!.inMinutes);
  return Duration(minutes: totalMinutes ~/ recordsWithDuration.length);
}

6.2 准时率计算

double _calculateOnTimeRate() {
  if (_sleepRecords.isEmpty) return 0.0;
  
  final bedtimeMinutes = _schedule.bedtime.hour * 60 + _schedule.bedtime.minute;
  final onTimeCount = _sleepRecords.where((r) {
    if (r.actualBedtime == null) return false;
    final actualMinutes = r.actualBedtime!.hour * 60 + r.actualBedtime!.minute;
    return actualMinutes <= bedtimeMinutes + 30; // 允许30分钟误差
  }).length;
  
  return onTimeCount / _sleepRecords.length;
}

6.3 睡眠质量分布计算

Map<SleepQuality, int> _calculateSleepQualityDistribution() {
  final distribution = <SleepQuality, int>{};
  for (final record in _sleepRecords) {
    if (record.quality != null) {
      distribution[record.quality!] = (distribution[record.quality!] ?? 0) + 1;
    }
  }
  return distribution;
}

七、状态管理流程

7.1 提醒状态流转

距离睡觉>1小时

距离睡觉<30分钟

已过睡觉时间

新的一天开始

用户已记录睡眠

标准卡片样式

渐变背景+提醒标签

橙色警告样式

7.2 记录睡眠流程

点击记录睡眠

弹出底部表单

选择睡觉日期时间

选择起床日期时间

选择睡眠质量

填写备注

时间是否有效?

保存记录

提示错误

更新统计图表

关闭弹窗

7.3 作息设置流程

修改睡觉时间

修改起床时间

切换提醒开关

选择提醒模式

选择提前时间

选择重复日期

进入作息页

显示当前设置

用户操作

打开TimePicker

打开TimePicker

更新提醒状态

更新提醒模式

更新提前分钟数

更新重复日期

保存新时间

刷新首页倒计时


八、扩展功能规划

8.1 后续版本规划

2024-01-07 2024-01-14 2024-01-21 2024-01-28 2024-02-04 2024-02-11 2024-02-18 2024-02-25 2024-03-03 2024-03-10 2024-03-17 2024-03-24 睡前倒计时 作息设置 睡眠记录 统计分析 白噪音助眠 智能睡眠分析 睡眠日记 好友PK 医生咨询 AI睡眠建议 V1.0 基础版本 V1.1 增强版本 V1.2 进阶版本 反向闹钟应用开发计划

8.2 功能扩展建议

8.2.1 白噪音助眠

帮助用户更快入睡:

  • 集成白噪音播放器
  • 支持雨声、海浪、森林等自然音效
  • 定时关闭功能
8.2.2 智能睡眠分析

基于传感器数据分析:

  • 监测睡眠深浅周期
  • 记录翻身次数
  • 生成睡眠报告
8.2.3 睡眠日记

记录睡前状态:

  • 语音记录心情
  • 记录咖啡因摄入
  • 记录运动情况

九、注意事项

9.1 开发注意事项

  1. 时间计算:注意跨天情况的处理,睡觉时间可能在第二天

  2. 异步操作:使用 context.mounted 检查避免 async gaps 问题

  3. 状态更新:修改作息后需要同步更新首页倒计时显示

  4. 数据验证:记录睡眠时验证起床时间必须晚于睡觉时间

9.2 常见问题

问题 原因 解决方案
倒计时显示错误 跨天计算未处理 检查是否加了24小时
弹窗报错 async gaps 使用 mounted 检查
统计不更新 状态未刷新 调用 setState
时间选择无效 上下文丢失 保存 context 引用

9.3 使用提示

🌙 睡眠健康小贴士 🌙

规律作息:每天同一时间睡觉和起床。
睡前放松:避免剧烈运动和刺激性内容。
环境优化:保持卧室黑暗、安静、凉爽。
远离屏幕:睡前一小时不看手机电脑。
适度饮食:避免睡前大量进食和饮水。


十、运行说明

10.1 环境要求

环境 版本要求
Flutter SDK >= 3.0.0
Dart SDK >= 2.17.0
鸿蒙OS API 21+

10.2 运行命令

# 查看可用设备
flutter devices

# 运行到Web服务器
flutter run -d web-server -t lib/main_reverse_alarm.dart --web-port 8098

# 运行到鸿蒙设备
flutter run -d 127.0.0.1:5555 lib/main_reverse_alarm.dart

# 运行到Windows
flutter run -d windows -t lib/main_reverse_alarm.dart

# 代码分析
flutter analyze lib/main_reverse_alarm.dart

十一、总结

反向闹钟应用通过创新的"提醒睡觉"理念,帮助用户建立健康的作息习惯。应用采用 Flutter + Material Design 3 技术栈,具有美观的界面和流畅的交互体验。核心功能包括睡前倒计时、作息设置、睡眠记录和统计分析,通过数据可视化帮助用户了解自己的睡眠状况。

技术亮点

  1. 创新的产品理念:反向思维,关注睡前而非起床
  2. 精确的时间计算:支持跨天计算,准确显示剩余时间
  3. 丰富的数据可视化:进度条、统计卡片、分布图表
  4. 灵活的提醒模式:四种模式适应不同用户需求
  5. 贴心的用户体验:每日小贴士、智能状态提示

核心代码文件

  • [main_reverse_alarm.dart](file:///f:/Flutter/flutter_harmonyos/lib/main_reverse_alarm.dart) - 完整应用代码

规律作息,健康生活

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐