番茄钟专注应用


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

适配的第三方库地址:

  • flutter_local_notifications: https://pub.dev/packages/flutter_local_notifications
  • shared_preferences: https://pub.dev/packages/shared_preferences
  • audioplayers: https://pub.dev/packages/audioplayers
  • wakelock: https://pub.dev/packages/wakelock

一、项目概述

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

1.1 应用简介

番茄钟专注应用是一款基于番茄工作法的时间管理工具,致力于帮助用户提高工作效率,培养专注习惯。应用支持自定义时长、休息提醒、专注统计、白噪音背景等功能,让用户在愉悦的氛围中高效完成工作。

应用以热情的橙红色为主色调,象征专注的热情与动力。涵盖计时器、统计分析、历史记录、设置中心四大模块。用户可以开始专注计时、查看统计数据、回顾历史记录、自定义设置,打造专属的专注体验。

1.2 核心功能

功能模块功能描述实现方式
番茄计时专注、短休息、长休息三种模式定时器
自定义时长自由设置专注和休息时长设置配置
专注类型工作、学习、阅读等多种类型分类管理
专注统计每日、每周专注数据统计数据分析
历史记录专注历史时间线展示数据存储
白噪音雨声、森林、海浪等背景音音频播放
提醒通知专注结束提醒通知本地通知
屏幕常亮专注时保持屏幕常亮系统控制

1.3 计时模式定义

序号模式名称Emoji默认时长描述
1专注🍅25分钟专注工作时间段
2短休息5分钟短暂休息调整
3长休息🌴15分钟较长休息放松

1.4 专注类型定义

序号类型名称Emoji颜色描述
1工作💼蓝色日常工作任务
2学习📚紫色学习知识技能
3阅读📖绿色阅读书籍文章
4编程💻橙色编写代码程序
5写作✍️粉色创作写作内容
6运动🏃青色锻炼身体运动
7冥想🧘棕色冥想放松身心
8其他📌灰色其他类型任务

1.5 白噪音类型定义

序号音效名称图标描述
1🔇关闭白噪音
2雨声💧淅淅沥沥的雨声
3森林🌲鸟语花香的森林
4海浪🌊波涛汹涌的海浪
5篝火🔥噼啪作响的篝火
6风声💨轻柔拂面的风声
7咖啡厅嘈杂温馨的咖啡厅
8夜晚🌙宁静祥和的夜晚

1.6 技术栈

技术领域技术选型版本要求
开发框架Flutter>= 3.0.0
编程语言Dart>= 2.17.0
设计规范Material Design 3-
本地通知flutter_local_notifications>= 16.0.0
数据存储shared_preferences>= 2.0.0
音频播放audioplayers>= 5.0.0
屏幕唤醒wakelock>= 0.2.0
目标平台鸿蒙OS / Android / iOSAPI 21+

1.7 项目结构

lib/
└── main_pomodoro_timer.dart
    ├── PomodoroTimerApp              # 应用入口
    ├── TimerMode                     # 计时模式枚举
    ├── WhiteNoise                    # 白噪音枚举
    ├── FocusCategory                 # 专注类型枚举
    ├── FocusSession                  # 专注会话模型
    ├── DailyStats                    # 每日统计模型
    ├── PomodoroSettings              # 番茄钟设置
    ├── PomodoroController            # 番茄钟控制器
    ├── PomodoroHomePage              # 主页面(底部导航)
    ├── _buildTimerPage               # 计时页
    ├── _buildStatsPage               # 统计页
    ├── _buildHistoryPage             # 历史页
    ├── _buildSettingsPage            # 设置页
    ├── TimerCirclePainter            # 计时圆环绘制器
    └── WeeklyChartPainter            # 周统计图表绘制器

二、系统架构

2.1 整体架构图

Data Layer

Business Layer

Presentation Layer

主页面
PomodoroHomePage

计时页

统计页

历史页

设置页

计时圆环

模式选择

控制按钮

今日摘要

周概览

分类分布

趋势图表

历史列表

日期详情

时间设置

自动化设置

提醒设置

白噪音选择

番茄钟控制器
PomodoroController

计时器管理
TimerManager

统计计算器
StatsCalculator

FocusSession
专注会话

DailyStats
每日统计

PomodoroSettings
设置配置

2.2 类图设计

uses

creates

calculates

has

uses

PomodoroTimerApp

+Widget build()

«enumeration»

TimerMode

+String label

+String emoji

+Color color

+focus()

+shortBreak()

+longBreak()

«enumeration»

WhiteNoise

+String label

+IconData icon

+none()

+rain()

+forest()

+ocean()

+fire()

+wind()

+cafe()

+night()

«enumeration»

FocusCategory

+String label

+String emoji

+Color color

+work()

+study()

+reading()

+coding()

+writing()

+exercise()

+meditation()

+other()

FocusSession

+String id

+DateTime startTime

+DateTime endTime

+int durationMinutes

+FocusCategory category

+String? note

+bool completed

+int tomatoCount

DailyStats

+DateTime date

+int totalMinutes

+int completedSessions

+int tomatoCount

+Map<FocusCategory,int> categoryMinutes

+String totalHoursText

PomodoroSettings

+int focusDuration

+int shortBreakDuration

+int longBreakDuration

+int sessionsBeforeLongBreak

+bool autoStartBreak

+bool autoStartFocus

+bool soundEnabled

+bool vibrationEnabled

+WhiteNoise whiteNoise

+copyWith()

PomodoroController

-TimerMode _currentMode

-Timer? _timer

-int _remainingSeconds

-bool _isRunning

-PomodoroSettings _settings

+TimerMode currentMode

+int remainingSeconds

+bool isRunning

+PomodoroSettings settings

+start()

+pause()

+reset()

+skip()

+setMode()

+setCategory()

+updateSettings()

2.3 页面导航流程

计时

统计

历史

设置

暂停

完成

跳过

应用启动

主页面

底部导航

计时页

统计页

历史页

设置页

选择模式

选择类型

开始计时

计时中

暂停状态

结束提醒

切换模式

记录会话

下一模式

查看统计

查看历史

修改设置

2.4 计时流程

定时器番茄钟控制器计时页用户定时器番茄钟控制器计时页用户loop[每秒更新]时间到点击开始start()记录开始时间启动定时器更新剩余时间通知UI更新显示倒计时点击暂停pause()取消定时器点击重置reset()重置时间时间结束保存会话记录切换到休息模式通知模式切换显示休息界面

三、核心模块设计

3.1 数据模型设计

3.1.1 计时模式枚举 (TimerMode)
enum TimerMode {
  focus(label: '专注', emoji: '🍅', color: Color(0xFFFF5722)),
  shortBreak(label: '短休息', emoji: '☕', color: Color(0xFF4CAF50)),
  longBreak(label: '长休息', emoji: '🌴', color: Color(0xFF2196F3));

  final String label;
  final String emoji;
  final Color color;
  const TimerMode({required this.label, required this.emoji, required this.color});
}
3.1.2 专注类型枚举 (FocusCategory)
enum FocusCategory {
  work(label: '工作', emoji: '💼', color: Color(0xFF2196F3)),
  study(label: '学习', emoji: '📚', color: Color(0xFF9C27B0)),
  reading(label: '阅读', emoji: '📖', color: Color(0xFF4CAF50)),
  coding(label: '编程', emoji: '💻', color: Color(0xFFFF9800)),
  writing(label: '写作', emoji: '✍️', color: Color(0xFFE91E63)),
  exercise(label: '运动', emoji: '🏃', color: Color(0xFF00BCD4)),
  meditation(label: '冥想', emoji: '🧘', color: Color(0xFF795548)),
  other(label: '其他', emoji: '📌', color: Color(0xFF607D8B));

  final String label;
  final String emoji;
  final Color color;
  const FocusCategory({required this.label, required this.emoji, required this.color});
}
3.1.3 专注会话模型 (FocusSession)
class FocusSession {
  final String id;
  final DateTime startTime;
  final DateTime endTime;
  final int durationMinutes;
  final FocusCategory category;
  final String? note;
  final bool completed;

  const FocusSession({
    required this.id,
    required this.startTime,
    required this.endTime,
    required this.durationMinutes,
    required this.category,
    this.note,
    required this.completed,
  });

  int get tomatoCount => (durationMinutes / 25).ceil();
}
3.1.4 每日统计模型 (DailyStats)
class DailyStats {
  final DateTime date;
  final int totalMinutes;
  final int completedSessions;
  final int tomatoCount;
  final Map<FocusCategory, int> categoryMinutes;

  const DailyStats({
    required this.date,
    this.totalMinutes = 0,
    this.completedSessions = 0,
    this.tomatoCount = 0,
    this.categoryMinutes = const {},
  });

  String get totalHoursText {
    final hours = totalMinutes ~/ 60;
    final minutes = totalMinutes % 60;
    return '${hours}h ${minutes}m';
  }
}
3.1.5 专注类型分布
35%25%15%10%8%4%2%1%专注类型分布示例工作学习编程阅读写作运动冥想其他

3.2 页面结构设计

3.2.1 主页面布局

PomodoroHomePage

IndexedStack

计时页

统计页

历史页

设置页

NavigationBar

计时 Tab

统计 Tab

历史 Tab

设置 Tab

3.2.2 计时页结构

计时页

SliverAppBar

计时圆环

模式选择器

控制按钮

今日摘要

渐变背景

模式Emoji

类型选择

倒计时显示

进度圆环

当前类型

专注模式

短休息

长休息

重置按钮

播放/暂停

跳过按钮

3.2.3 统计页结构

统计页

SliverAppBar

周概览

分类分布

周趋势图

总时长

总番茄

类型进度条

百分比显示

柱状图

日期标签

3.2.4 设置页结构

设置页

时间设置

自动化设置

提醒设置

白噪音选择

专注时长

短休息时长

长休息时长

长休息间隔

自动开始休息

自动开始专注

声音提醒

震动提醒

3.3 番茄钟控制器逻辑

开始

暂停

重置

跳过

切换模式

初始化

加载设置

设置默认模式

用户操作

操作类型

启动定时器

停止定时器

重置时间

完成当前会话

切换模式

每秒更新

时间结束?

保存会话记录

计算统计数据

切换到下一模式

3.4 统计计算逻辑

获取会话列表

按日期分组

计算每日统计

计算总时长

计算完成次数

计算番茄数

计算分类分布

汇总周统计

生成分类报告

生成周趋势数据


四、UI设计规范

4.1 配色方案

应用以热情的橙红色为主色调,象征专注的热情与动力:

颜色类型色值用途
主色#FF5722 (Deep Orange)专注模式、主题元素
辅助色#FF7043渐变效果
第三色#FF8A65卡片背景
强调色#E64A19按钮高亮
背景色#FAFAFA页面背景
卡片背景#FFFFFF信息卡片
专注色#FF5722专注模式
短休息色#4CAF50短休息模式
长休息色#2196F3长休息模式

4.2 计时模式配色

模式色值视觉效果
专注#FF5722橙红色
短休息#4CAF50绿色
长休息#2196F3蓝色

4.3 专注类型配色

类型色值视觉效果
工作#2196F3蓝色
学习#9C27B0紫色
阅读#4CAF50绿色
编程#FF9800橙色
写作#E91E63粉色
运动#00BCD4青色
冥想#795548棕色
其他#607D8B灰色

4.4 字体规范

元素字号字重颜色
页面标题24pxBold主色
倒计时48pxBold当前模式色
模式名称16pxMedium当前模式色
统计数字24pxBold主色
日期显示16pxBold#000000
分类名称14pxRegular#333333

4.5 组件规范

4.5.1 计时圆环
┌─────────────────────────────────────┐
│                                     │
│           ╭──────────────╮          │
│          ╱                ╲         │
│         │                  │        │
│         │     25:00       │        │
│         │                  │        │
│         │     专注        │        │
│         │                  │        │
│         │   💼 工作       │        │
│          ╲                ╱         │
│           ╰──────────────╯          │
│                                     │
└─────────────────────────────────────┘
4.5.2 模式选择器
┌─────────────────────────────────────┐
│  [🍅 专注]  [☕ 短休息]  [🌴 长休息] │
└─────────────────────────────────────┘
4.5.3 控制按钮
┌─────────────────────────────────────┐
│         🔄        ▶️        ⏭️      │
│        重置     开始/暂停   跳过     │
└─────────────────────────────────────┘
4.5.4 今日摘要
┌─────────────────────────────────────┐
│   ⏱️          🔥          🏆       │
│  125分钟     5个番茄     5次完成    │
└─────────────────────────────────────┘
4.5.5 统计卡片
┌─────────────────────────────────────┐
│  本周概览                            │
│  ┌─────────────┐ ┌─────────────┐   │
│  │ ⏱️ 总时长   │ │ 🔥 总番茄   │   │
│  │   12h 30m  │ │    25      │   │
│  └─────────────┘ └─────────────┘   │
└─────────────────────────────────────┘
4.5.6 分类分布
┌─────────────────────────────────────┐
│  分类分布                            │
│                                     │
│  💼 工作  350分钟 (35.0%)           │
│  ═══════════════●────────────       │
│                                     │
│  📚 学习  250分钟 (25.0%)           │
│  ═══════●────────────────────       │
│                                     │
│  💻 编程  150分钟 (15.0%)           │
│  ═══●───────────────────────        │
└─────────────────────────────────────┘

五、核心功能实现

5.1 番茄钟控制器实现

class PomodoroController extends ChangeNotifier {
  TimerMode _currentMode = TimerMode.focus;
  Timer? _timer;
  int _remainingSeconds = 25 * 60;
  bool _isRunning = false;
  PomodoroSettings _settings = const PomodoroSettings();

  TimerMode get currentMode => _currentMode;
  int get remainingSeconds => _remainingSeconds;
  bool get isRunning => _isRunning;

  void start() {
    if (_isRunning) return;
    _isRunning = true;
    _startTimer();
    notifyListeners();
  }

  void pause() {
    if (!_isRunning) return;
    _isRunning = false;
    _stopTimer();
    notifyListeners();
  }

  void toggle() {
    if (_isRunning) {
      pause();
    } else {
      start();
    }
  }

  void reset() {
    _stopTimer();
    _isRunning = false;
    _setDurationForMode(_currentMode);
    notifyListeners();
  }
}

5.2 定时器实现

void _startTimer() {
  _timer = Timer.periodic(const Duration(seconds: 1), (timer) {
    if (_remainingSeconds > 0) {
      _remainingSeconds--;
      notifyListeners();
    } else {
      _completeSession();
      _moveToNextMode();
      notifyListeners();
    }
  });
}

void _stopTimer() {
  _timer?.cancel();
  _timer = null;
}

5.3 模式切换实现

void setMode(TimerMode mode) {
  _stopTimer();
  _currentMode = mode;
  _setDurationForMode(mode);
  notifyListeners();
}

void _setDurationForMode(TimerMode mode) {
  switch (mode) {
    case TimerMode.focus:
      _remainingSeconds = _settings.focusDuration * 60;
      break;
    case TimerMode.shortBreak:
      _remainingSeconds = _settings.shortBreakDuration * 60;
      break;
    case TimerMode.longBreak:
      _remainingSeconds = _settings.longBreakDuration * 60;
      break;
  }
}

void _moveToNextMode() {
  if (_currentMode == TimerMode.focus) {
    if (_completedSessions % _settings.sessionsBeforeLongBreak == 0) {
      setMode(TimerMode.longBreak);
    } else {
      setMode(TimerMode.shortBreak);
    }
  } else {
    setMode(TimerMode.focus);
  }
}

5.4 统计计算实现

void _calculateDailyStats() {
  final statsMap = <DateTime, DailyStats>{};
  
  for (var session in _sessions) {
    final date = DateTime(
      session.startTime.year,
      session.startTime.month,
      session.startTime.day
    );
    
    if (!statsMap.containsKey(date)) {
      statsMap[date] = DailyStats(date: date);
    }
    
    final oldStats = statsMap[date]!;
    final categoryMinutes = Map<FocusCategory, int>.from(oldStats.categoryMinutes);
    categoryMinutes[session.category] = 
      (categoryMinutes[session.category] ?? 0) + session.durationMinutes;
    
    statsMap[date] = DailyStats(
      date: date,
      totalMinutes: oldStats.totalMinutes + session.durationMinutes,
      completedSessions: oldStats.completedSessions + (session.completed ? 1 : 0),
      tomatoCount: oldStats.tomatoCount + session.tomatoCount,
      categoryMinutes: categoryMinutes,
    );
  }
  
  _dailyStats.clear();
  _dailyStats.addAll(statsMap.values.toList()
    ..sort((a, b) => b.date.compareTo(a.date)));
}

5.5 计时圆环绘制实现

class TimerCirclePainter extends CustomPainter {
  final double progress;
  final Color color;
  final double strokeWidth;

  
  void paint(Canvas canvas, Size size) {
    final center = Offset(size.width / 2, size.height / 2);
    final radius = (size.width - strokeWidth) / 2;

    final backgroundPaint = Paint()
      ..color = color.withValues(alpha: 0.1)
      ..style = PaintingStyle.stroke
      ..strokeWidth = strokeWidth;

    canvas.drawCircle(center, radius, backgroundPaint);

    final progressPaint = Paint()
      ..color = color
      ..style = PaintingStyle.stroke
      ..strokeWidth = strokeWidth
      ..strokeCap = StrokeCap.round;

    final sweepAngle = 2 * pi * progress;
    canvas.drawArc(
      Rect.fromCircle(center: center, radius: radius),
      -pi / 2,
      sweepAngle,
      false,
      progressPaint,
    );
  }
}

六、交互设计

6.1 计时流程

定时器控制器计时页用户定时器控制器计时页用户loop[每秒]选择专注类型setCategory()点击开始start()启动定时器更新剩余时间通知更新显示倒计时点击暂停pause()停止定时器点击重置reset()重置显示

6.2 设置修改流程

时间设置

自动化设置

提醒设置

白噪音

打开设置页

显示当前设置

修改类型

弹出时长选择器

切换开关

切换开关

选择音效

滑动选择时长

确认修改

更新设置

保存到本地

应用新设置

6.3 统计查看流程

滚动

滚动

切换Tab

点击

打开统计页

显示周概览

查看分类分布

查看周趋势

打开历史页

查看日期列表

展开日期详情

查看分类明细


七、扩展功能规划

7.1 后续版本规划

2024-01-072024-01-142024-01-212024-01-282024-02-042024-02-112024-02-182024-02-252024-03-032024-03-102024-03-172024-03-24基础UI框架 计时器核心 统计功能 本地通知 数据持久化 白噪音播放 屏幕常亮 成就系统 数据同步 V1.0 基础版本V1.1 增强版本V1.2 进阶版本番茄钟专注应用开发计划

7.2 功能扩展建议

7.2.1 成就系统

成就功能:

  • 连续专注天数成就
  • 累计番茄数成就
  • 专注类型成就
  • 特殊节日成就
7.2.2 数据同步

同步功能:

  • 云端数据备份
  • 多设备同步
  • 数据导出
  • 数据恢复
7.2.3 社交功能

社交功能:

  • 分享专注成果
  • 好友排行榜
  • 专注挑战
  • 团队协作

八、注意事项

8.1 开发注意事项

  1. 后台运行:确保计时器在后台能正常运行

  2. 通知权限:申请本地通知权限

  3. 屏幕常亮:专注时保持屏幕常亮

  4. 数据持久化:正确保存用户设置和专注记录

  5. 电量优化:优化定时器减少电量消耗

8.2 常见问题

问题原因解决方案
计时不准确后台被杀死使用前台服务
通知不显示权限未授予申请通知权限
数据丢失未正确保存使用事务存储
屏幕熄灭未设置常亮使用wakelock
白噪音中断音频焦点丢失正确处理音频焦点

8.3 使用技巧

🍅 番茄钟专注使用技巧 🍅

时间管理

  • 选择适合的专注时长
  • 合理安排休息时间
  • 坚持每日专注习惯
  • 记录专注心得

效率提升

  • 选择合适的专注类型
  • 开启白噪音辅助
  • 关闭干扰通知
  • 保持专注环境

数据分析

  • 定期查看统计数据
  • 分析专注规律
  • 调整工作节奏
  • 设定专注目标

九、鸿蒙适配说明

9.1 权限配置

ohos/entry/src/main/module.json5 中添加权限:

{
  "module": {
    "requestPermissions": [
      {"name": "ohos.permission.INTERNET"},
      {"name": "ohos.permission.VIBRATE"},
      {"name": "ohos.permission.KEEP_BACKGROUND_RUNNING"}
    ]
  }
}

9.2 第三方库适配状态

第三方库适配状态说明
flutter_local_notifications✅ 已适配本地通知
shared_preferences✅ 已适配数据存储
audioplayers✅ 已适配音频播放
wakelock✅ 已适配屏幕唤醒

9.3 运行命令

# 查看可用设备
flutter devices

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

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

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

十、总结

番茄钟专注应用为用户提供了一套完整的时间管理解决方案。应用支持番茄工作法计时器,支持自定义时长、休息提醒、专注统计、白噪音背景等功能,帮助用户提高工作效率,培养专注习惯。

核心功能涵盖番茄计时、自定义时长、专注类型、专注统计、历史记录、白噪音、提醒通知、屏幕常亮八大模块。用户可以开始专注计时、查看统计数据、回顾历史记录、自定义设置,打造专属的专注体验。

应用采用 Material Design 3 设计规范,以热情的橙红色为主色调,象征专注的热情与动力。通过本应用,希望能够帮助用户科学管理时间,提升工作效率,享受专注带来的成就感。

番茄钟专注——让专注成为习惯


Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐