影子收藏家应用
欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net
一、项目概述
运行效果图



1.1 应用简介
影子收藏家是一款独特的摄影记录应用,灵感来源于对光影之美的追求。应用鼓励用户每天拍摄一张影子的照片,记录生活中那些转瞬即逝的光影瞬间。一年后,应用会生成一份专属的"影子年度报告",回顾这一年的光影旅程。
影子是光的伴侣,是时间的印记。通过收藏影子,我们记录的不只是光影的变化,更是时间的流逝和生活的轨迹。每一张影子照片都是一个故事,承载着特定的时间、地点、天气和心情。
1.2 核心功能
| 功能模块 | 功能描述 | 实现方式 |
|---|---|---|
| 影子拍摄 | 拍摄并记录影子 | 相机调用 + 表单 |
| 相册浏览 | 查看所有收藏的影子 | 网格布局 + 卡片 |
| 统计分析 | 分析收藏数据 | 图表可视化 |
| 年度报告 | 生成年度总结 | 数据汇总 + 展示 |
| 类型分类 | 8种影子类型 | 枚举定义 |
| 时间记录 | 5个时间段 | 枚举定义 |
| 天气记录 | 4种天气状况 | 枚举定义 |
1.3 影子类型定义
| 序号 | 类型名称 | Emoji | 主题色 | 描述 |
|---|---|---|---|---|
| 1 | 树木 | 🌳 | #4CAF50 | 树木的影子 |
| 2 | 建筑 | 🏢 | #607D8B | 建筑物的影子 |
| 3 | 人物 | 👤 | #9E9E9E | 人物的影子 |
| 4 | 动物 | 🐕 | #8D6E63 | 动物的影子 |
| 5 | 物体 | 📦 | #FF9800 | 物体的影子 |
| 6 | 自然 | 🌿 | #66BB6A | 自然景观的影子 |
| 7 | 艺术 | 🎨 | #AB47BC | 艺术造型的影子 |
| 8 | 抽象 | ✨ | #42A5F5 | 抽象形状的影子 |
1.4 拍摄时间定义
| 序号 | 时段名称 | Emoji | 时间范围 | 主题色 |
|---|---|---|---|---|
| 1 | 清晨 | 🌅 | 6:00-9:00 | #FFE082 |
| 2 | 正午 | ☀️ | 11:00-13:00 | #FFF176 |
| 3 | 下午 | 🌤️ | 14:00-17:00 | #FFD54F |
| 4 | 傍晚 | 🌇 | 17:00-19:00 | #FFAB91 |
| 5 | 夜晚 | 🌙 | 19:00-22:00 | #90A4AE |
1.5 天气状况定义
| 序号 | 天气名称 | Emoji | 主题色 | 描述 |
|---|---|---|---|---|
| 1 | 晴天 | ☀️ | #FFF59D | 阳光明媚 |
| 2 | 多云 | ☁️ | #B0BEC5 | 云层较多 |
| 3 | 阴天 | 🌥️ | #90A4AE | 阴云密布 |
| 4 | 雨天 | 🌧️ | #81D4FA | 下雨天 |
1.6 技术栈
| 技术领域 | 技术选型 | 版本要求 |
|---|---|---|
| 开发框架 | Flutter | >= 3.0.0 |
| 编程语言 | Dart | >= 2.17.0 |
| 设计规范 | Material Design 3 | - |
| 状态管理 | setState | - |
| 数据存储 | 内存列表 | - |
| 目标平台 | 鸿蒙OS / Web | API 21+ |
1.7 项目结构
lib/
└── main_shadow_collector.dart
├── ShadowCollectorApp # 应用入口
├── ShadowType # 影子类型枚举
├── TimeOfDay # 拍摄时间枚举
├── WeatherCondition # 天气状况枚举
├── ShadowPhoto # 影子照片模型
├── ShadowCollectorHomePage # 主页面(底部导航)
├── _buildHomePage # 首页
├── _buildGalleryPage # 相册页面
├── _buildStatsPage # 统计页面
└── YearReportPage # 年度报告页面
二、系统架构
2.1 整体架构图
Data Layer
Business Layer
Presentation Layer
主页面
ShadowCollectorHomePage
首页
相册
统计
进度卡片
今日卡片
快捷操作
照片网格
照片卡片
概览统计
类型分布
时间分布
天气分布
拍摄管理
数据统计
报告生成
ShadowPhoto
影子照片
ShadowType
影子类型
TimeOfDay
拍摄时间
WeatherCondition
天气状况
2.2 类图设计
manages
displays
has
has
has
ShadowCollectorApp
+Widget build()
<<enumeration>>
ShadowType
+String label
+String emoji
+Color color
+tree()
+building()
+person()
+animal()
+object()
+nature()
+artistic()
+abstract()
<<enumeration>>
TimeOfDay
+String label
+String emoji
+String timeRange
+Color color
+morning()
+noon()
+afternoon()
+evening()
+night()
<<enumeration>>
WeatherCondition
+String label
+String emoji
+Color color
+sunny()
+cloudy()
+overcast()
+rainy()
ShadowPhoto
+String id
+DateTime date
+String? imagePath
+ShadowType type
+TimeOfDay timeOfDay
+WeatherCondition weather
+String? location
+String? notes
+List<String> tags
ShadowCollectorHomePage
-int _selectedIndex
-List<ShadowPhoto> _photos
+Widget build()
-_takePhoto()
-_showAddPhotoDialog()
-_showYearReport()
YearReportPage
+List<ShadowPhoto> photos
+Widget build()
2.3 页面导航流程
首页
相册
统计
否
是
应用启动
首页
底部导航
查看进度
浏览照片
查看统计
查看今日状态
今日已记录?
点击拍摄
显示记录信息
拍摄/选择照片
填写信息
保存记录
查看照片详情
查看概览
查看分布
点击年度报告
年度报告页面
查看总结
查看精彩瞬间
查看洞察
2.4 数据流程
数据层 拍摄弹窗 首页 用户 数据层 拍摄弹窗 首页 用户 点击拍摄按钮 显示表单 选择影子类型 选择拍摄时间 选择天气状况 填写地点和备注 点击保存 创建ShadowPhoto 更新照片列表 显示成功提示
三、核心模块设计
3.1 数据模型设计
3.1.1 影子类型枚举 (ShadowType)
dart
enum ShadowType {
tree('树木', '🌳', Color(0xFF4CAF50)),
building('建筑', '🏢', Color(0xFF607D8B)),
person('人物', '👤', Color(0xFF9E9E9E)),
animal('动物', '🐕', Color(0xFF8D6E63)),
object('物体', '📦', Color(0xFFFF9800)),
nature('自然', '🌿', Color(0xFF66BB6A)),
artistic('艺术', '🎨', Color(0xFFAB47BC)),
abstract('抽象', '✨', Color(0xFF42A5F5));
final String label;
final String emoji;
final Color color;
const ShadowType(this.label, this.emoji, this.color);
}
3.1.2 拍摄时间枚举 (TimeOfDay)
dart
enum TimeOfDay {
morning('清晨', '🌅', '6:00-9:00', Color(0xFFFFE082)),
noon('正午', '☀️', '11:00-13:00', Color(0xFFFFF176)),
afternoon('下午', '🌤️', '14:00-17:00', Color(0xFFFFD54F)),
evening('傍晚', '🌇', '17:00-19:00', Color(0xFFFFAB91)),
night('夜晚', '🌙', '19:00-22:00', Color(0xFF90A4AE));
final String label;
final String emoji;
final String timeRange;
final Color color;
const TimeOfDay(this.label, this.emoji, this.timeRange, this.color);
}
3.1.3 天气状况枚举 (WeatherCondition)
dart
enum WeatherCondition {
sunny('晴天', '☀️', Color(0xFFFFF59D)),
cloudy('多云', '☁️', Color(0xFFB0BEC5)),
overcast('阴天', '🌥️', Color(0xFF90A4AE)),
rainy('雨天', '🌧️', Color(0xFF81D4FA));
final String label;
final String emoji;
final Color color;
const WeatherCondition(this.label, this.emoji, this.color);
}
3.1.4 影子照片模型 (ShadowPhoto)
dart
class ShadowPhoto {
final String id; // 唯一标识
final DateTime date; // 拍摄日期
final String? imagePath; // 照片路径
final ShadowType type; // 影子类型
final TimeOfDay timeOfDay; // 拍摄时间
final WeatherCondition weather; // 天气状况
final String? location; // 拍摄地点
final String? notes; // 备注
final List<String> tags; // 标签
}
3.1.5 影子类型分布
27% 20% 17% 13% 10% 7% 3% 3% 影子类型分布示例 树木 建筑 人物 动物 物体 自然 艺术 抽象
3.2 页面结构设计
3.2.1 主页面布局
ShadowCollectorHomePage
IndexedStack
首页
相册
统计
NavigationBar
首页 Tab
相册 Tab
统计 Tab
FloatingActionButton
3.2.2 首页结构
首页
SliverAppBar
进度卡片
今日卡片
快捷操作
年度进度
收藏天数
进度条
今日状态
拍摄按钮
拍摄影子
从相册选择
年度报告
3.2.3 相册页面结构
相册页面
SliverAppBar
照片网格
照片卡片
渐变背景
类型Emoji
类型名称
日期信息
时间信息
3.2.4 年度报告页面结构
年度报告
报告头部
年度总结
精彩瞬间
年度洞察
年份标题
收藏数量
最喜欢类型
收藏天数
完成率
照片网格
发现
亮点
建议
3.3 统计计算逻辑
获取照片列表
计算类型统计
计算时间统计
计算天气统计
遍历照片
统计各类型数量
计算百分比
遍历照片
统计各时间数量
计算百分比
遍历照片
统计各天气数量
计算百分比
生成统计图表
3.4 年度报告生成
开始生成报告
汇总数据
计算总天数
找出最常类型
计算完成率
选择精彩瞬间
年度总结
精彩瞬间展示
生成洞察
完成报告
四、UI设计规范
4.1 配色方案
应用以蓝灰色为主色调,营造沉稳、文艺的氛围:
| 颜色类型 | 色值 | 用途 |
|---|---|---|
| 主色 | #37474F (Blue Grey) | 导航、强调元素 |
| 树木色 | #4CAF50 | 树木类型标识 |
| 建筑色 | #607D8B | 建筑类型标识 |
| 人物色 | #9E9E9E | 人物类型标识 |
| 动物色 | #8D6E63 | 动物类型标识 |
| 物体色 | #FF9800 | 物体类型标识 |
| 自然色 | #66BB6A | 自然类型标识 |
| 艺术色 | #AB47BC | 艺术类型标识 |
| 抽象色 | #42A5F5 | 抽象类型标识 |
4.2 时间配色
| 时段 | 色值 | 视觉效果 |
|---|---|---|
| 清晨 | #FFE082 | 温暖黄色 |
| 正午 | #FFF176 | 明亮黄色 |
| 下午 | #FFD54F | 金黄色 |
| 傍晚 | #FFAB91 | 橙红色 |
| 夜晚 | #90A4AE | 灰蓝色 |
4.3 字体规范
| 元素 | 字号 | 字重 | 颜色 |
|---|---|---|---|
| 页面标题 | 24px | Bold | 主色 |
| 进度数字 | 24px | Bold | 黑色 |
| 卡片标题 | 18px | Bold | 黑色 |
| 类型名称 | 16px | Bold | 黑色 |
| 日期信息 | 12px | Regular | 白色 |
| 统计数字 | 20px | Bold | 黑色 |
4.4 组件规范
4.4.1 进度卡片
┌─────────────────────────────────────┐
│ 年度进度 ◯ 8% │
│ 30 / 365 天 │
│ │
│ ▓▓▓▓▓▓▓░░░░░░░░░░░░░░░░░░░░░░░░░ │
└─────────────────────────────────────┘
4.4.2 今日卡片
┌─────────────────────────────────────┐
│ ┌────┐ 今日影子 │
│ │ 📷 │ 还没有记录今天的影子哦 │
│ └────┘ [拍摄] │
└─────────────────────────────────────┘
4.4.3 照片卡片
┌─────────────────────┐
│ │
│ [渐变背景] │
│ 🌳 │
│ 树木 │
│ │
│ ┌───────────────┐ │
│ │ 4/8 │ │
│ │ 🌤️ 下午 │ │
│ └───────────────┘ │
└─────────────────────┘
4.4.4 统计卡片
┌─────────────────────────────────────┐
│ 概览 │
│ │
│ 📷 30 📅 8% 🔥 5 │
│ 收藏数量 年度完成 连续天数 │
└─────────────────────────────────────┘
五、核心功能实现
5.1 进度计算
dart
Widget _buildProgressCard() {
final totalDays = 365;
final collectedDays = _photos.length;
final progress = collectedDays / totalDays;
return Card(
child: Column(
children: [
Text('$collectedDays / $totalDays 天'),
CircularProgressIndicator(value: progress),
LinearProgressIndicator(value: progress),
],
),
);
}
5.2 连续天数计算
dart
int _getStreak() {
var streak = 0;
var checkDate = DateTime.now();
for (var i = 0; i < _photos.length; i++) {
final hasPhoto = _photos.any((p) =>
p.date.year == checkDate.year &&
p.date.month == checkDate.month &&
p.date.day == checkDate.day);
if (hasPhoto) {
streak++;
checkDate = checkDate.subtract(const Duration(days: 1));
} else {
break;
}
}
return streak;
}
5.3 类型统计
dart
Widget _buildTypeStats(Map<ShadowType, int> stats) {
final sortedStats = stats.entries.toList()
..sort((a, b) => b.value.compareTo(a.value));
return Column(
children: sortedStats.map((entry) {
final total = stats.values.fold<int>(0, (sum, v) => sum + v);
final percentage = total > 0 ? (entry.value / total * 100) : 0;
return Row(
children: [
Text(entry.key.emoji),
Text(entry.key.label),
LinearProgressIndicator(value: percentage / 100),
Text('${entry.value}张'),
],
);
}).toList(),
);
}
5.4 年度报告生成
dart
Widget _buildSummary() {
final typeStats = <ShadowType, int>{};
for (var photo in photos) {
typeStats[photo.type] = (typeStats[photo.type] ?? 0) + 1;
}
final topType = typeStats.entries.isEmpty
? null
: typeStats.entries.reduce((a, b) => a.value > b.value ? a : b);
return Card(
child: Column(
children: [
_buildSummaryItem(
'最喜欢的影子类型',
topType != null ? '${topType.key.emoji} ${topType.key.label}' : '暂无数据',
),
_buildSummaryItem('收藏天数', '${photos.length} 天'),
_buildSummaryItem('完成率', '${(photos.length / 365 * 100).toStringAsFixed(1)}%'),
],
),
);
}
六、交互设计
6.1 拍摄流程
数据层 拍摄弹窗 首页 用户 数据层 拍摄弹窗 首页 用户 点击拍摄按钮 显示表单 显示预览 选择影子类型 选择拍摄时间 选择天气状况 填写地点 填写备注 点击保存 创建ShadowPhoto 更新列表 显示成功提示
6.2 浏览流程
打开相册
加载照片列表
网格布局展示
用户浏览
查看照片
显示类型Emoji
显示日期时间
显示渐变背景
6.3 统计流程
打开统计页面
计算概览
显示收藏数量
显示完成率
显示连续天数
计算类型分布
计算时间分布
计算天气分布
七、扩展功能规划
7.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 核心功能 统计分析 年度报告 真实拍照 地理定位 分享功能 云端同步 社交功能 AI识别 V1.0 基础版本 V1.1 增强版本 V1.2 进阶版本 影子收藏家应用开发计划
7.2 功能扩展建议
7.2.1 真实拍照
拍照功能增强:
- 调用设备相机
- 照片压缩存储
- 多张照片选择
- 照片编辑功能
7.2.2 地理定位
位置功能增强:
- 自动获取位置
- 地图标记展示
- 位置统计
- 位置搜索
7.2.3 社交功能
分享交流功能:
- 照片分享
- 社区展示
- 点赞评论
- 影子挑战
八、注意事项
8.1 开发注意事项
-
数据持久化:照片数据需要本地存储
-
照片压缩:避免占用过多存储空间
-
权限管理:需要相机和存储权限
-
性能优化:大量照片时的加载优化
-
用户体验:拍摄流程要简洁流畅
8.2 常见问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 照片加载慢 | 图片过大 | 压缩图片 |
| 数据丢失 | 未保存 | 实现本地存储 |
| 权限被拒 | 未请求权限 | 引导用户授权 |
| 统计错误 | 数据未更新 | 刷新统计 |
8.3 设计理念
📸 影子收藏家理念 📸
影子,是光的伴侣,
是时间的印记。
每一张影子照片,
都是一个故事,
承载着特定的时间、地点、天气和心情。
通过收藏影子,
我们记录的不只是光影的变化,
更是时间的流逝和生活的轨迹。
一年365天,
365个影子,
365个瞬间。
当一年结束,
翻开这份影子年度报告,
你会发现:
原来,时间可以这样被记录。
收藏影子,记录时间
九、运行说明
9.1 环境要求
| 环境 | 版本要求 |
|---|---|
| Flutter SDK | >= 3.0.0 |
| Dart SDK | >= 2.17.0 |
| 鸿蒙OS | API 21+ |
9.2 运行命令
bash
# 查看可用设备
flutter devices
# 运行到Web服务器
flutter run -d web-server -t lib/main_shadow_collector.dart --web-port 8125
# 运行到鸿蒙设备
flutter run -d 127.0.0.1:5555 lib/main_shadow_collector.dart
# 运行到Windows
flutter run -d windows -t lib/main_shadow_collector.dart
# 代码分析
flutter analyze lib/main_shadow_collector.dart
十、总结
影子收藏家通过影子拍摄、相册浏览、统计分析、年度报告四大模块,为用户提供了一个独特的光影记录平台。应用鼓励用户每天拍摄一张影子的照片,记录生活中那些转瞬即逝的光影瞬间。
核心功能涵盖影子拍摄、类型分类、时间记录、天气记录、统计分析、年度报告六大模块。影子拍摄支持选择影子类型、拍摄时间、天气状况等信息;类型分类提供8种影子类型供选择;时间记录分为5个时间段;天气记录支持4种天气状况;统计分析通过图表展示收藏数据;年度报告汇总一年的收藏成果。
应用采用Material Design 3设计规范,以蓝灰色为主色调,营造沉稳、文艺的氛围。通过本应用,希望能够帮助用户记录光影之美,感受时间的流逝,珍藏生活的轨迹。
收藏影子,记录时间