Flutter 框架跨平台鸿蒙开发 - 颜色情绪
运行效果图颜色情绪应用是一款独特的情绪追踪与可视化工具,灵感源自GitHub的贡献度热力图。用户每天选择一种颜色来代表当天的心情,经过一年的积累,最终生成一幅独一无二的年度情绪色谱。应用以粉红色为主色调,传递温暖、关怀的情感基调。应用涵盖了今日记录、年度色谱、情绪统计、日历视图四大模块,支持12种情绪颜色,每种颜色对应特定的情绪状态和描述。通过颜色选择、色谱展示、数据分析等功能,帮助用户更好地觉察
颜色情绪应用
欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net
一、项目概述
运行效果图




1.1 应用简介
颜色情绪应用是一款独特的情绪追踪与可视化工具,灵感源自GitHub的贡献度热力图。用户每天选择一种颜色来代表当天的心情,经过一年的积累,最终生成一幅独一无二的年度情绪色谱。应用以粉红色为主色调,传递温暖、关怀的情感基调。
应用涵盖了今日记录、年度色谱、情绪统计、日历视图四大模块,支持12种情绪颜色,每种颜色对应特定的情绪状态和描述。通过颜色选择、色谱展示、数据分析等功能,帮助用户更好地觉察和了解自己的情绪变化规律。
1.2 核心功能
| 功能模块 | 功能描述 | 实现方式 |
|---|---|---|
| 今日记录 | 选择当日心情颜色 | 弹窗选择器 |
| 年度色谱 | GitHub风格热力图 | 自定义网格 |
| 情绪统计 | 分布与占比分析 | 饼图+进度条 |
| 日历视图 | 月度情绪日历 | GridView |
| 情绪洞察 | 智能分析与建议 | 算法判断 |
1.3 情绪颜色定义
| 序号 | 情绪名称 | Emoji | 主题色 | 描述 |
|---|---|---|---|---|
| 1 | 开心 | 😊 | #FFEB3B | 阳光灿烂 |
| 2 | 平静 | 😌 | #4CAF50 | 宁静致远 |
| 3 | 活力 | ⚡ | #FF5722 | 精力充沛 |
| 4 | 爱意 | 💕 | #E91E63 | 温暖甜蜜 |
| 5 | 创意 | 🎨 | #9C27B0 | 灵感迸发 |
| 6 | 祥和 | 🌸 | #03A9F4 | 心如止水 |
| 7 | 希望 | 🌟 | #00BCD4 | 期待美好 |
| 8 | 感恩 | 🙏 | #8BC34A | 心怀感激 |
| 9 | 焦虑 | 😰 | #FF9800 | 有些担忧 |
| 10 | 忧伤 | 😢 | #607D8B | 情绪低落 |
| 11 | 愤怒 | 😠 | #F44336 | 心烦意乱 |
| 12 | 疲惫 | 😴 | #795548 | 需要休息 |
1.4 情绪分类
| 分类 | 包含情绪 | 特点 |
|---|---|---|
| 积极情绪 | 开心、平静、活力、爱意、创意、祥和、希望、感恩 | 正向能量,促进身心健康 |
| 消极情绪 | 焦虑、忧伤、愤怒、疲惫 | 需要关注和调节 |
1.5 技术栈
| 技术领域 | 技术选型 | 版本要求 |
|---|---|---|
| 开发框架 | Flutter | >= 3.0.0 |
| 编程语言 | Dart | >= 2.17.0 |
| 设计规范 | Material Design 3 | - |
| 动画控制 | AnimationController | - |
| 图表绘制 | CustomPainter | - |
| 状态管理 | setState | - |
| 目标平台 | 鸿蒙OS / Web | API 21+ |
1.6 项目结构
lib/
└── main_color_mood.dart
├── ColorMoodApp # 应用入口
├── MoodColor # 情绪颜色枚举
├── DailyMood # 每日情绪模型
├── ColorMoodHomePage # 主页面(底部导航)
├── _buildTodayPage # 今日页面
├── _buildYearSpectrumPage # 年度色谱页面
├── _buildStatsPage # 统计页面
├── _buildCalendarPage # 日历页面
└── MoodPieChartPainter # 饼图绘制器
二、系统架构
2.1 整体架构图
2.2 类图设计
2.3 页面导航流程
2.4 数据流向图
三、核心模块设计
3.1 数据模型设计
3.1.1 情绪颜色枚举 (MoodColor)
enum MoodColor {
joyful('开心', '😊', Color(0xFFFFEB3B), '阳光灿烂'),
calm('平静', '😌', Color(0xFF4CAF50), '宁静致远'),
energetic('活力', '⚡', Color(0xFFFF5722), '精力充沛'),
love('爱意', '💕', Color(0xFFE91E63), '温暖甜蜜'),
creative('创意', '🎨', Color(0xFF9C27B0), '灵感迸发'),
peaceful('祥和', '🌸', Color(0xFF03A9F4), '心如止水'),
hopeful('希望', '🌟', Color(0xFF00BCD4), '期待美好'),
grateful('感恩', '🙏', Color(0xFF8BC34A), '心怀感激'),
anxious('焦虑', '😰', Color(0xFFFF9800), '有些担忧'),
sad('忧伤', '😢', Color(0xFF607D8B), '情绪低落'),
angry('愤怒', '😠', Color(0xFFF44336), '心烦意乱'),
tired('疲惫', '😴', Color(0xFF795548), '需要休息');
final String label; // 情绪名称
final String emoji; // 代表表情
final Color color; // 主题颜色
final String description; // 情绪描述
}
3.1.2 每日情绪模型 (DailyMood)
class DailyMood {
final DateTime date; // 日期
final MoodColor mood; // 情绪类型
final String? note; // 备注(可选)
}
3.1.3 情绪颜色分布
3.2 页面结构设计
3.2.1 主页面布局
3.2.2 今日页面结构
3.2.3 年度色谱结构
3.2.4 统计页面结构
3.3 统计计算流程
四、UI设计规范
4.1 配色方案
应用以粉红色为主色调,传递温暖关怀的情感基调:
| 颜色类型 | 色值 | 用途 |
|---|---|---|
| 主色 | #E91E63 (Pink) | 导航、强调元素 |
| 开心 | #FFEB3B | 金黄色 |
| 平静 | #4CAF50 | 绿色 |
| 活力 | #FF5722 | 橙红色 |
| 爱意 | #E91E63 | 粉红色 |
| 创意 | #9C27B0 | 紫色 |
| 祥和 | #03A9F4 | 天蓝色 |
| 希望 | #00BCD4 | 青色 |
| 感恩 | #8BC34A | 浅绿色 |
| 焦虑 | #FF9800 | 橙色 |
| 忧伤 | #607D8B | 蓝灰色 |
| 愤怒 | #F44336 | 红色 |
| 疲惫 | #795548 | 棕色 |
4.2 情绪色彩心理
| 情绪分类 | 颜色特征 | 心理暗示 |
|---|---|---|
| 开心/活力 | 暖黄色、橙红色 | 温暖、活力、积极 |
| 平静/祥和 | 绿色、蓝色 | 宁静、平和、放松 |
| 爱意/感恩 | 粉红色、浅绿色 | 温暖、感激、关爱 |
| 创意/希望 | 紫色、青色 | 创造力、期待、憧憬 |
| 焦虑/忧伤 | 橙色、蓝灰色 | 警示、低落、需要关注 |
| 愤怒/疲惫 | 红色、棕色 | 强烈情绪、需要休息 |
4.3 字体规范
| 元素 | 字号 | 字重 | 颜色 |
|---|---|---|---|
| 应用标题 | 20px | Bold | #000000 |
| 日期显示 | 16px | Regular | #666666 |
| 情绪标签 | 24px | Bold | 情绪色 |
| 情绪描述 | 14px | Regular | #666666 |
| 统计数值 | 18px | Bold | #000000 |
| 图例文字 | 12px | Regular | #000000 |
4.4 组件规范
4.4.1 心情选择圆圈
┌─────────────┐
│ │
│ ┌───┐ │
│ │ 😊 │ │
│ └───┘ │
│ │
│ 开心 │
│ 阳光灿烂 │
└─────────────┘
4.4.2 情绪选择卡片
┌─────────────────┐
│ 😊 │
│ │
│ 开心 │
│ 阳光灿烂 │
└─────────────────┘
4.4.3 色谱网格单元
┌──┬──┬──┬──┬──┬──┬──┐
│██│██│░░│██│██│░░│░░│
├──┼──┼──┼──┼──┼──┼──┤
│░░│██│██│██│░░│██│██│
├──┼──┼──┼──┼──┼──┼──┤
│██│░░│░░│██│██│██│░░│
└──┴──┴──┴──┴──┴──┴──┘
██ = 已记录(情绪色)
░░ = 未记录(灰色)
4.4.4 快速统计卡片
┌────────────────────────────────────────┐
│ 📅 😊 ❓ │
│ 120 75% 开心 │
│ 记录天数 积极情绪 最常心情 │
└────────────────────────────────────────┘
五、核心功能实现
5.1 情绪选择器实现
void _showMoodSelector() {
showModalBottomSheet(
context: context,
isScrollControlled: true,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(24)),
),
builder: (context) => DraggableScrollableSheet(
initialChildSize: 0.7,
maxChildSize: 0.9,
minChildSize: 0.5,
expand: false,
builder: (context, scrollController) => Container(
padding: const EdgeInsets.all(20),
child: GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
mainAxisSpacing: 12,
crossAxisSpacing: 12,
childAspectRatio: 0.85,
),
itemCount: MoodColor.values.length,
itemBuilder: (context, index) {
final mood = MoodColor.values[index];
return _buildMoodCard(mood);
},
),
),
),
);
}
5.2 年度色谱网格实现
Widget _buildYearSpectrumGrid() {
final now = DateTime.now();
final startOfYear = DateTime(now.year, 1, 1);
final endOfYear = DateTime(now.year, 12, 31);
final weeks = <List<DateTime>>[];
var currentWeek = <DateTime>[];
var firstDayOfWeek = startOfYear.weekday;
for (int i = 1; i < firstDayOfWeek; i++) {
currentWeek.add(DateTime(now.year, 1, 1 - (firstDayOfWeek - i)));
}
for (var date = startOfYear;
date.isBefore(endOfYear) || date.isAtSameMomentAs(endOfYear);
date = date.add(const Duration(days: 1))) {
if (currentWeek.length == 7) {
weeks.add(currentWeek);
currentWeek = [];
}
currentWeek.add(date);
}
if (currentWeek.isNotEmpty) {
weeks.add(currentWeek);
}
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: weeks.map((week) {
return Column(
children: week.map((date) {
final mood = _moodRecords[DateTime(date.year, date.month, date.day)];
return Container(
width: 14,
height: 14,
margin: const EdgeInsets.all(1),
decoration: BoxDecoration(
color: mood != null ? mood.mood.color : Colors.grey[200],
borderRadius: BorderRadius.circular(2),
),
);
}).toList(),
);
}).toList(),
),
);
}
5.3 统计计算实现
Map<String, dynamic> _getStatistics() {
final now = DateTime.now();
final yearRecords = _moodRecords.entries
.where((e) => e.key.year == now.year)
.map((e) => e.value)
.toList();
final moodCounts = <MoodColor, int>{};
for (var mood in MoodColor.values) {
moodCounts[mood] = yearRecords.where((r) => r.mood == mood).length;
}
final sortedMoods = moodCounts.entries.toList()
..sort((a, b) => b.value.compareTo(a.value));
final positiveMoods = [MoodColor.joyful, MoodColor.calm, MoodColor.energetic,
MoodColor.love, MoodColor.creative, MoodColor.peaceful,
MoodColor.hopeful, MoodColor.grateful];
final positiveDays = yearRecords.where((r) => positiveMoods.contains(r.mood)).length;
final positivePercent = totalDays > 0 ? (positiveDays / totalDays * 100) : 0.0;
return {
'totalDays': totalDays,
'moodCounts': moodCounts,
'sortedMoods': sortedMoods,
'mostCommon': mostCommon,
'positivePercent': positivePercent,
};
}
5.4 饼图绘制实现
class MoodPieChartPainter extends CustomPainter {
final Map<MoodColor, int> moodCounts;
MoodPieChartPainter({required this.moodCounts});
void paint(Canvas canvas, Size size) {
final center = Offset(size.width / 2, size.height / 2);
final radius = min(size.width, size.height) / 2 - 20;
final total = moodCounts.values.fold(0, (sum, v) => sum + v);
if (total == 0) return;
double startAngle = -pi / 2;
final sortedEntries = moodCounts.entries.toList()
..sort((a, b) => b.value.compareTo(a.value));
for (var entry in sortedEntries) {
if (entry.value <= 0) continue;
final sweepAngle = (entry.value / total) * 2 * pi;
final paint = Paint()
..color = entry.key.color
..style = PaintingStyle.fill;
canvas.drawArc(
Rect.fromCircle(center: center, radius: radius),
startAngle,
sweepAngle,
true,
paint,
);
startAngle += sweepAngle;
}
final innerPaint = Paint()
..color = Colors.white
..style = PaintingStyle.fill;
canvas.drawCircle(center, radius * 0.5, innerPaint);
}
}
5.5 脉冲动画实现
void initState() {
super.initState();
_pulseController = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 1500),
)..repeat(reverse: true);
}
Widget _buildPulsingCircle(DailyMood? todayMood) {
return AnimatedBuilder(
animation: _pulseController,
builder: (context, child) {
return Transform.scale(
scale: 1.0 + _pulseController.value * 0.05,
child: Container(
width: 120,
height: 120,
decoration: BoxDecoration(
color: todayMood?.mood.color.withValues(alpha: 0.3) ?? Colors.grey[200],
shape: BoxShape.circle,
boxShadow: todayMood != null
? [
BoxShadow(
color: todayMood.mood.color.withValues(alpha: 0.3),
blurRadius: 20,
spreadRadius: 5,
),
]
: null,
),
child: Text(todayMood?.mood.emoji ?? '➕'),
),
);
},
);
}
六、交互设计
6.1 心情记录流程
6.2 色谱浏览流程
6.3 日历导航流程
七、扩展功能规划
7.1 后续版本规划
7.2 功能扩展建议
7.2.1 数据持久化
本地数据存储:
- 使用SharedPreferences存储基础设置
- 使用SQLite存储每日情绪记录
- 支持数据导出为JSON格式
7.2.2 情绪备注功能
丰富记录内容:
- 添加文字备注
- 支持添加照片
- 记录触发事件
7.2.3 智能分析功能
深度分析:
- 情绪周期分析
- 关联因素识别
- 个性化建议生成
八、注意事项
8.1 开发注意事项
-
日期处理:使用DateTime统一处理日期,注意时区问题
-
Map键值:情绪记录使用DateTime作为键,需规范化为年月日
-
颜色透明度:使用withValues方法设置透明度
-
动画释放:AnimationController需要在dispose中释放
8.2 常见问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 色谱显示不完整 | 日期计算错误 | 检查周数计算逻辑 |
| 情绪记录丢失 | DateTime键不匹配 | 规范化为年月日 |
| 饼图不显示 | 总数为0 | 添加总数判断 |
| 动画卡顿 | 未释放Controller | 在dispose中释放 |
8.3 情绪关怀寄语
🌈 情绪关怀寄语 🌈
每一种情绪都是生命的一部分,
开心让我们感受阳光,
忧伤让我们学会珍惜。
记录情绪不是为了评判,
而是为了更好地了解自己。
愿你的年度色谱,
绘出属于自己的彩虹。
记录每一天,遇见更好的自己 🌟
九、运行说明
9.1 环境要求
| 环境 | 版本要求 |
|---|---|
| Flutter SDK | >= 3.0.0 |
| Dart SDK | >= 2.17.0 |
| 鸿蒙OS | API 21+ |
9.2 运行命令
# 查看可用设备
flutter devices
# 运行到Web服务器
flutter run -d web-server -t lib/main_color_mood.dart --web-port 8115
# 运行到鸿蒙设备
flutter run -d 127.0.0.1:5555 lib/main_color_mood.dart
# 运行到Windows
flutter run -d windows -t lib/main_color_mood.dart
# 代码分析
flutter analyze lib/main_color_mood.dart
十、总结
颜色情绪应用通过今日记录、年度色谱、情绪统计、日历视图四大模块,为用户提供了一个直观的情绪追踪与可视化工具。应用支持12种情绪颜色,每种颜色对应特定的情绪状态,帮助用户更好地觉察和了解自己的情绪变化规律。
核心功能涵盖心情记录、色谱展示、数据分析、日历浏览四大模块。心情记录支持快速选择当日情绪;色谱展示以GitHub风格热力图呈现年度情绪变化;数据分析提供情绪分布和占比统计;日历浏览支持按月查看和编辑情绪记录。
应用采用Material Design 3设计规范,以粉红色为主色调,界面温暖友好。通过本应用,希望能够帮助用户建立情绪觉察的习惯,用色彩记录生活,用数据了解自己。
用颜色记录心情,用色谱见证成长
更多推荐
所有评论(0)