专注森林应用


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

一、项目概述

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

1.1 应用简介

专注森林是一款创新的专注力管理应用,灵感来源于经典的Forest应用。应用将专注过程游戏化,用户在专注时种植虚拟树木,如果分心放弃,树木就会枯萎。通过这种正向激励机制,帮助用户培养专注习惯,同时积累属于自己的虚拟森林。

应用以绿色为主色调,营造自然清新的视觉体验。涵盖专注计时、森林展示、数据统计、个性设置四大模块,支持8种树木类型和4种专注时长,通过树木成长动画和枯萎机制增强用户的专注动力。

1.2 核心功能

功能模块 功能描述 实现方式
专注计时 倒计时专注模式 Timer定时器
树木成长 实时成长动画 AnimationController
枯萎机制 放弃导致枯萎 状态判定逻辑
森林展示 已种树木展示 GridView网格
数据统计 专注时长统计 CustomPainter图表
树种选择 多种树木类型 枚举配置

1.3 树木类型系统

序号 树种名称 Emoji 颜色 最短时长 最长时长
1 橡树 🌳 #4CAF50 25分钟 60分钟
2 松树 🌲 #2E7D32 30分钟 90分钟
3 樱花 🌸 #E91E63 20分钟 45分钟
4 枫树 🍁 #FF5722 25分钟 75分钟
5 竹子 🎋 #8BC34A 15分钟 30分钟
6 棕榈 🌴 #009688 35分钟 120分钟
7 圣诞树 🎄 #1B5E20 40分钟 150分钟
8 盆栽 🪴 #66BB6A 10分钟 20分钟

1.4 树木成长阶段

序号 阶段名称 Emoji 进度范围
1 种子 🌱 0% - 20%
2 幼苗 🌿 20% - 50%
3 成长中 🌱 50% - 100%
4 成熟 🌳 100%
5 枯萎 🥀 放弃后

1.5 专注时长选项

序号 时长名称 分钟数 图标
1 短时专注 15分钟 timer_10
2 中等专注 25分钟 timer
3 长时专注 45分钟 timer_3
4 超长专注 60分钟 timer_s

1.6 技术栈

技术领域 技术选型 版本要求
开发框架 Flutter >= 3.0.0
编程语言 Dart >= 2.17.0
设计规范 Material Design 3 -
定时器 Timer -
动画控制 AnimationController -
目标平台 鸆蒙OS / Web API 21+

1.7 项目结构

lib/
└── main_focus_forest.dart
    ├── FocusForestApp         # 应用入口
    ├── TreeType               # 树种类型枚举
    ├── TreeState              # 树木状态枚举
    ├── FocusDuration          # 专注时长枚举
    ├── Tree                   # 树木数据模型
    ├── FocusSession           # 专注记录模型
    ├── FocusForestHomePage    # 主页面(底部导航)
    ├── _buildFocusPage        # 专注页面
    ├── _buildForestPage       # 森林页面
    ├── _buildStatsPage        # 统计页面
    ├── _buildSettingsPage     # 设置页面
    └── WeeklyFocusPainter     # 周图表绘制器

二、系统架构

2.1 整体架构图

Logic Layer

Presentation Layer

Data Layer

Tree
树木模型

TreeType
树种类型

TreeState
树木状态

FocusSession
专注记录

主页面
FocusForestHomePage

专注页面

森林页面

统计页面

设置页面

计时器界面

树木可视化

倒计时显示

进度条

森林网格

树木卡片

详情弹窗

统计概览

周度图表

树种分布

专注计时器
Timer

树木成长系统
GrowthSystem

枯萎机制
WitherMechanism

2.2 类图设计

has

has

references

manages

records

renders

FocusForestApp

+Widget build()

«enumeration»

TreeType

+String label

+String emoji

+Color color

+int minMinutes

+int maxMinutes

+oak()

+pine()

+cherry()

+maple()

+bamboo()

+palm()

+christmas()

+bonsai()

«enumeration»

TreeState

+String label

+String emoji

+seed()

+sprout()

+growing()

+mature()

+dead()

«enumeration»

FocusDuration

+String label

+int minutes

+IconData icon

+short()

+medium()

+long()

+extra()

Tree

+String id

+TreeType type

+TreeState state

+DateTime plantedAt

+int targetMinutes

+int elapsedSeconds

+bool isAlive

+double growthProgress

+int get elapsedMinutes

+double get progress

+void updateState()

FocusSession

+String id

+DateTime startTime

+DateTime? endTime

+int durationMinutes

+bool completed

+TreeType treeType

FocusForestHomePage

-int _selectedIndex

-List<Tree> _forest

-List<FocusSession> _sessions

-Tree? _currentTree

-Timer? _focusTimer

-bool _isFocusing

-int _selectedDuration

-TreeType _selectedTreeType

-AnimationController _treeAnimationController

+Widget build()

-_startFocus()

-_completeFocus()

-_witherTree()

WeeklyFocusPainter

+List<FocusSession> sessions

+void paint()

+bool shouldRepaint()

2.3 专注流程图

开始专注

选择时长

选择树种

点击开始

创建树木对象

启动计时器

每秒更新

更新进度

更新树木状态

进度>=100%?

专注完成

用户放弃?

树木枯萎

添加到森林

记录成功

添加枯萎树

记录失败

2.4 树木成长流程

树木系统 计时器 界面 用户 树木系统 计时器 界面 用户 loop [每秒] 开始专注 创建树木 返回Tree对象 启动Timer 更新进度 计算成长进度 更新树木状态 更新显示 完成专注 标记成熟 添加到森林

三、核心模块设计

3.1 数据模型设计

3.1.1 树种类型枚举 (TreeType)
enum TreeType {
  oak('橡树', '🌳', Color(0xFF4CAF50), 25, 60),
  pine('松树', '🌲', Color(0xFF2E7D32), 30, 90),
  cherry('樱花', '🌸', Color(0xFFE91E63), 20, 45),
  maple('枫树', '🍁', Color(0xFFFF5722), 25, 75),
  bamboo('竹子', '🎋', Color(0xFF8BC34A), 15, 30),
  palm('棕榈', '🌴', Color(0xFF009688), 35, 120),
  christmas('圣诞树', '🎄', Color(0xFF1B5E20), 40, 150),
  bonsai('盆栽', '🪴', Color(0xFF66BB6A), 10, 20);

  final String label;       // 树种名称
  final String emoji;       // 代表表情
  final Color color;        // 主题颜色
  final int minMinutes;     // 最短专注时长
  final int maxMinutes;     // 最长专注时长
}
3.1.2 树木状态枚举 (TreeState)
enum TreeState {
  seed('种子', '🌱'),
  sprout('幼苗', '🌿'),
  growing('成长中', '🌱'),
  mature('成熟', '🌳'),
  dead('枯萎', '🥀');

  final String label;   // 状态名称
  final String emoji;   // 代表表情
}
3.1.3 树木模型 (Tree)
class Tree {
  final String id;              // 唯一标识
  final TreeType type;          // 树种类型
  TreeState state;              // 当前状态
  final DateTime plantedAt;     // 种植时间
  final int targetMinutes;      // 目标时长
  int elapsedSeconds;           // 已过秒数
  bool isAlive;                 // 是否存活
  double growthProgress;        // 成长进度

  int get elapsedMinutes;       // 已过分钟数
  double get progress;          // 完成进度

  void updateState() {
    if (!isAlive) {
      state = TreeState.dead;
      return;
    }
    final progress = this.progress;
    if (progress < 0.2) state = TreeState.seed;
    else if (progress < 0.5) state = TreeState.sprout;
    else if (progress < 1.0) state = TreeState.growing;
    else state = TreeState.mature;
  }
}
3.1.4 专注记录模型 (FocusSession)
class FocusSession {
  final String id;              // 唯一标识
  final DateTime startTime;     // 开始时间
  final DateTime? endTime;      // 结束时间
  final int durationMinutes;    // 专注时长
  final bool completed;         // 是否完成
  final TreeType treeType;      // 树种类型
}
3.1.5 树种时长分布
28% 22% 15% 13% 9% 6% 4% 3% 树种专注时长范围 橡树 (25-60分钟) 松树 (30-90分钟) 樱花 (20-45分钟) 枫树 (25-75分钟) 竹子 (15-30分钟) 棕榈 (35-120分钟) 圣诞树 (40-150分钟) 盆栽 (10-20分钟)

3.2 页面结构设计

3.2.1 主页面布局

FocusForestHomePage

IndexedStack

专注页面

森林页面

统计页面

设置页面

NavigationBar

专注 Tab

森林 Tab

统计 Tab

设置 Tab

3.2.2 专注页面结构

空闲

专注中

空闲

专注中

专注页面

SliverAppBar

控制区域

专注状态

空闲视图

专注视图

树木选择

时长选择

开始按钮

树木动画

倒计时

进度条

放弃按钮

专注状态

设置控件

放弃控件

3.2.3 森林页面结构

森林页面

AppBar

GridView

标题

信息按钮

树木卡片网格

单个树木卡片

树木Emoji

树种名称

专注时长

点击显示详情

底部弹窗

详细信息

种植日期

3.3 树木成长计算

< 0.2

0.2-0.5

0.5-1.0

>= 1.0

每秒更新

elapsedSeconds++

计算progress

progress = elapsedSeconds / targetSeconds

progress范围

状态=种子

状态=幼苗

状态=成长中

状态=成熟

更新UI

完成专注


四、UI设计规范

4.1 配色方案

应用以绿色为主色调,营造自然清新的视觉体验:

颜色类型 色值 用途
主色 #4CAF50 (Green) 导航、强调元素
深绿 #2E7D32 渐变过渡
浅绿 #81C784 背景渐变
背景白 #FFFFFF 卡片背景
文字灰 #9E9E9E 次要文字

4.2 树种配色

树种 色值 视觉效果
橡树 #4CAF50 自然绿色
松树 #2E7D32 深邃绿色
樱花 #E91E63 浪漫粉色
枫树 #FF5722 温暖橙色
竹子 #8BC34A 清新浅绿
棕榈 #009688 热带青色
圣诞树 #1B5E20 浓郁深绿
盆栽 #66BB6A 柔和绿色

4.3 状态配色

状态 色值 视觉效果
成长中 树种色 生机勃勃
成熟 树种色 完成状态
枯萎 #9E9E9E 灰暗无光

4.4 字体规范

元素 字号 字重 颜色
倒计时 56px Bold 树种色
状态标签 16px SemiBold 树种色
页面标题 20px Bold #000000
树种名称 12px Medium 树种色
时长文字 14px Medium #666666

4.5 组件规范

4.5.1 专注界面
┌─────────────────────────────────────┐
│                                     │
│            ✨  🌿  ✨               │
│                                     │
│              🌳                     │
│                                     │
│            25:00                    │
│           [ 成长中 ]                │
│                                     │
│     ████████████░░░░░░░░░░░░       │
│                                     │
└─────────────────────────────────────┘
4.5.2 时长选择器
┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐
│    ⏱️    │  │    ⏱️    │  │    ⏱️    │  │    ⏱️    │
│  15分钟  │  │  25分钟  │  │  45分钟  │  │  60分钟  │
│ 短时专注 │  │ 中等专注 │  │ 长时专注 │  │ 超长专注 │
└──────────┘  └──────────┘  └──────────┘  └──────────┘
4.5.3 树种选择器
┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐
│   🌳   │ │   🌲   │ │   🌸   │ │   🍁   │
│  橡树  │ │  松树  │ │  樱花  │ │  枫树  │
└────────┘ └────────┘ └────────┘ └────────┘
┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐
│   🎋   │ │   🌴   │ │   🎄   │ │   🪴   │
│  竹子  │ │  棕榈  │ │ 圣诞树 │ │  盆栽  │
└────────┘ └────────┘ └────────┘ └────────┘
4.5.4 森林卡片
┌─────────────────┐
│       🌳        │
│      橡树       │
│     25分钟      │
└─────────────────┘
4.5.5 完成弹窗
┌─────────────────────────────────────┐
│              🎉                     │
│            专注完成!               │
│      成功种植了一棵橡树             │
│                                     │
│      ⏱️ 25分钟      🌳 15棵        │
│                                     │
│           [ 太棒了! ]              │
└─────────────────────────────────────┘

五、核心功能实现

5.1 专注计时器实现

void _startFocus() {
  setState(() {
    _isFocusing = true;
    _currentTree = Tree(
      id: 'tree_${DateTime.now().millisecondsSinceEpoch}',
      type: _selectedTreeType,
      plantedAt: DateTime.now(),
      targetMinutes: _selectedDuration,
    );
  });

  _treeAnimationController.forward();
  _startFocusTimer();
}

void _startFocusTimer() {
  _focusTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
    if (_currentTree == null) {
      timer.cancel();
      return;
    }

    setState(() {
      _currentTree!.elapsedSeconds++;
      _currentTree!.growthProgress = _currentTree!.progress;
      _currentTree!.updateState();
    });

    if (_currentTree!.progress >= 1.0) {
      _completeFocus();
    }
  });
}

5.2 完成专注实现

void _completeFocus() {
  _focusTimer?.cancel();

  setState(() {
    if (_currentTree != null) {
      _currentTree!.isAlive = true;
      _currentTree!.state = TreeState.mature;
      _forest.insert(0, _currentTree!);

      _sessions.insert(0, FocusSession(
        id: 'session_${DateTime.now().millisecondsSinceEpoch}',
        startTime: _currentTree!.plantedAt,
        endTime: DateTime.now(),
        durationMinutes: _currentTree!.targetMinutes,
        completed: true,
        treeType: _currentTree!.type,
      ));

      _totalFocusMinutes += _currentTree!.targetMinutes;
      _totalTrees++;
    }
    _isFocusing = false;
    _currentTree = null;
  });

  _showCompletionDialog();
}

5.3 枯萎机制实现

void _witherTree() {
  _focusTimer?.cancel();

  setState(() {
    if (_currentTree != null) {
      _currentTree!.isAlive = false;
      _currentTree!.state = TreeState.dead;
      _forest.insert(0, _currentTree!);

      _sessions.insert(0, FocusSession(
        id: 'session_${DateTime.now().millisecondsSinceEpoch}',
        startTime: _currentTree!.plantedAt,
        endTime: DateTime.now(),
        durationMinutes: _currentTree!.elapsedMinutes,
        completed: false,
        treeType: _currentTree!.type,
      ));

      _witheredTrees++;
    }
    _isFocusing = false;
    _currentTree = null;
  });
}

5.4 树木状态更新

void updateState() {
  if (!isAlive) {
    state = TreeState.dead;
    return;
  }

  final progress = this.progress;
  if (progress < 0.2) {
    state = TreeState.seed;
  } else if (progress < 0.5) {
    state = TreeState.sprout;
  } else if (progress < 1.0) {
    state = TreeState.growing;
  } else {
    state = TreeState.mature;
  }
}

5.5 时间格式化

String _formatTime(int seconds) {
  if (seconds < 0) seconds = 0;
  final minutes = seconds ~/ 60;
  final secs = seconds % 60;
  return '${minutes.toString().padLeft(2, '0')}:${secs.toString().padLeft(2, '0')}';
}

六、树木成长系统

6.1 成长阶段判定

0% - 20%

20% - 50%

50% - 100%

100%

计算进度

progress值

种子阶段 🌱

幼苗阶段 🌿

成长阶段 🌱

成熟阶段 🌳

放弃专注

枯萎状态 🥀

显示种子Emoji

显示幼苗Emoji

显示成长Emoji

显示成熟Emoji

显示枯萎Emoji

6.2 树种解锁条件

时长>=10分钟

时长>=15分钟

时长>=20分钟

时长>=25分钟

时长>=30分钟

时长>=35分钟

时长>=40分钟

选择专注时长

检查树种要求

解锁盆栽

解锁竹子

解锁樱花

解锁橡树/枫树

解锁松树

解锁棕榈

解锁圣诞树

6.3 动画效果

粒子系统 动画控制器 界面 用户 粒子系统 动画控制器 界面 用户 loop [每帧] 开始专注 启动成长动画 持续更新 更新粒子位置 返回粒子坐标 重绘树木 完成专注 停止动画 显示完成弹窗

七、交互设计

7.1 开始专注流程

树木系统 计时器 主页面 用户 树木系统 计时器 主页面 用户 选择专注时长 选择树种 点击开始按钮 创建树木对象 返回Tree 启动Timer 开始倒计时 显示专注界面

7.2 放弃专注流程

用户操作

继续专注

确认放弃

专注中

点击放弃

确认弹窗

树木枯萎

树木状态=dead
添加到森林
记录失败

7.3 森林浏览流程

点击树木

点击信息

进入森林页面

加载树木列表

显示网格布局

用户操作

显示详情弹窗

显示统计信息

查看树木详情

关闭弹窗

查看森林统计

关闭弹窗


八、扩展功能规划

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 专注计时功能 树木成长系统 森林展示功能 成就系统 每日目标 白噪音功能 社交分享 好友森林 云端同步 V1.0 基础版本 V1.1 增强版本 V1.2 进阶版本 专注森林应用开发计划

8.2 功能扩展建议

8.2.1 成就系统

成就类型:

  • 累计种植树木数量
  • 连续专注天数
  • 单次专注时长
  • 特殊树种收集
8.2.2 白噪音功能

音效类型:

  • 雨声
  • 森林鸟鸣
  • 海浪声
  • 咖啡馆环境
8.2.3 社交功能

社交特性:

  • 分享森林截图
  • 好友排行榜
  • 共同专注
  • 森林参观

九、注意事项

9.1 开发注意事项

  1. 定时器管理:Timer需要在dispose时取消

  2. 动画释放:AnimationController需要在dispose时释放

  3. 状态更新:专注中禁止切换页面

  4. 树种限制:根据时长限制可选树种

  5. 数据持久化:考虑使用本地存储保存数据

9.2 常见问题

问题 原因 解决方案
计时器不停止 Timer未取消 在dispose中取消
树木状态错误 进度计算错误 检查progress计算
动画卡顿 Controller未释放 在dispose中释放
树种选择异常 时长限制错误 检查minMinutes

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_focus_forest.dart --web-port 8114

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

# 运行到Edge浏览器
flutter run -d edge lib/main_focus_forest.dart

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

十一、总结

专注森林应用通过专注计时、树木成长、森林展示、数据统计四大模块,为用户提供了一个游戏化的专注力管理平台。应用支持8种树木类型和4种专注时长,通过树木成长动画和枯萎机制增强用户的专注动力。

核心功能涵盖专注计时、树木成长、枯萎机制、森林展示、数据统计五大模块。计时系统通过Timer实现精确的倒计时;成长系统根据进度更新树木状态;枯萎机制在用户放弃时标记树木死亡;森林系统展示所有已种树木;统计系统提供周度图表和树种分布。

应用采用Material Design 3设计规范,以绿色为主色调,营造自然清新的视觉体验。通过本应用,希望能够帮助用户培养专注习惯,在专注中收获属于自己的森林。

专注时种树,分心树就枯萎

Logo

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

更多推荐