Flutter 框架跨平台鸿蒙开发 - 记忆热力图

记忆热力图应用


欢迎加入开源鸿蒙跨平台社区:

https://openharmonycrossplatform.csdn.net

一、项目概述

运行效果图

1.1 应用简介

记忆热力图是一款独特的记忆管理应用,通过热力图的形式在日历上展示哪些日子值得记住。应用借鉴了GitHub贡献图的视觉设计,将抽象的记忆数据转化为直观的热力图,让用户能够一目了然地看到自己的记忆分布。

应用以红色为主色调,象征热情与记忆的温度。界面设计简洁优雅,采用卡片式布局。通过不同深浅的红色表示记忆的强度,从淡粉到深红,直观地展示了记忆的重要程度。用户可以通过点击日期查看当天的记忆详情,也可以长按日期快速添加新的记忆。

1.2 核心功能

功能模块 功能描述 实现方式
热力图日历 日历热力图展示 GridView网格
记忆记录 添加记忆事件 对话框表单
强度标记 五级记忆强度 颜色编码
时间线 记忆时间线展示 列表视图
统计分析 记忆数据分析 图表展示
标签系统 记忆分类标签 标签选择

1.3 记忆强度等级

应用定义了五级记忆强度:

等级 名称 颜色 说明
1 淡忘 #FFE5E5 记忆模糊,需要提醒
2 记得 #FFB3B3 记忆清晰,印象深刻
3 清晰 #FF8080 记忆深刻,细节丰富
4 深刻 #FF4D4D 记忆深刻,难以忘怀
5 难忘 #FF0000 永生难忘,刻骨铭心

1.4 技术栈

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

1.5 项目结构

复制代码
lib/
└── main_memory_heatmap.dart
    ├── MemoryHeatmapApp           # 应用入口
    ├── MemoryIntensity            # 记忆强度枚举
    ├── Memory                     # 记忆模型
    ├── MemoryHeatmapHomePage      # 主页面(底部导航)
    ├── _buildHeatmapPage          # 热力图页面
    ├── _buildTimelinePage         # 时间线页面
    └── _buildStatsPage            # 统计页面

二、设计理念

2.1 热力图可视化

记忆热力图
日历网格
颜色编码
交互设计
月份切换
日期选择
记忆展示
淡忘 浅色
记得 中色
难忘 深色
点击查看
长按添加
滑动切换

2.2 记忆强度模型

记忆强度
淡忘
颜色浅粉
记忆模糊
需要提醒
记得
颜色中粉
记忆清晰
印象不错
清晰
颜色深粉
记忆深刻
细节丰富
深刻
颜色浅红
记忆深刻
难以忘怀
难忘
颜色深红
永生难忘
刻骨铭心

2.3 色彩体系

应用采用红色为主色调:

颜色类型 色值 RGB 用途
主色 #FF6B6B 255,107,107 导航、按钮、强调
辅助色 #FF8E8E 255,142,142 渐变、次要元素
淡忘 #FFE5E5 255,229,229 一级记忆
记得 #FFB3B3 255,179,179 二级记忆
清晰 #FF8080 255,128,128 三级记忆
深刻 #FF4D4D 255,77,77 四级记忆
难忘 #FF0000 255,0,0 五级记忆

2.4 记忆生命周期

存储 添加对话框 热力图 用户 存储 添加对话框 热力图 用户 浏览日历 显示热力图 长按日期 打开对话框 填写记忆 保存记忆 更新热力图 点击日期 显示记忆详情


三、系统架构

3.1 整体架构图

Data Layer
Business Layer
Presentation Layer
主页面

MemoryHeatmapHomePage
热力图页
时间线页
统计页
日历网格
强度图例
记忆详情
时间线列表
统计卡片
分布图表
记忆管理

CRUD操作
强度计算

颜色映射
统计分析

数据聚合
Memory

记忆模型
MemoryIntensity

强度枚举
Map

日期索引

3.2 类图设计

manages
uses
has
MemoryHeatmapApp
+Widget build()
<<enumeration>>
MemoryIntensity
+none 无
+low 淡忘
+medium 记得
+high 清晰
+intense 深刻
+unforgettable 难忘
+String label
+Color color
+int level
Memory
+String id
+DateTime date
+String title
+String description
+MemoryIntensity intensity
+List<String> tags
+String emoji
+DateTime createdAt
MemoryHeatmapHomePage
-int _currentIndex
-List<Memory> _memories
-DateTime _selectedMonth
-DateTime _selectedDate
-Map~DateTime,List<Memory~> _memoryMap
-AnimationController _pulseController
+void _addMemory()
+void _initializeDemoData()

3.3 记忆添加流程

存储 状态管理 对话框 日历 用户 存储 状态管理 对话框 日历 用户 长按日期 打开添加对话框 填写标题 选择强度 添加标签 选择表情 点击保存 创建Memory对象 添加到memories列表 更新memoryMap 刷新热力图


四、核心功能实现

4.1 热力图日历

热力图日历是应用的核心组件:

dart 复制代码
Widget _buildHeatmapCalendar() {
  final firstDayOfMonth = DateTime(_selectedMonth.year, _selectedMonth.month, 1);
  final lastDayOfMonth = DateTime(_selectedMonth.year, _selectedMonth.month + 1, 0);
  final firstWeekday = firstDayOfMonth.weekday % 7;
  final daysInMonth = lastDayOfMonth.day;

  return Container(
    padding: const EdgeInsets.all(16),
    child: Column(
      children: [
        // 星期标题
        _buildWeekdayHeaders(),
        // 日期网格
        GridView.builder(
          gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 7,
            mainAxisSpacing: 8,
            crossAxisSpacing: 8,
          ),
          itemCount: firstWeekday + daysInMonth,
          itemBuilder: (context, index) {
            if (index < firstWeekday) {
              return const SizedBox.shrink();
            }
            
            final day = index - firstWeekday + 1;
            final date = DateTime(_selectedMonth.year, _selectedMonth.month, day);
            final memories = _memoryMap[date] ?? [];
            final intensity = memories.isEmpty
                ? MemoryIntensity.none
                : memories.map((m) => m.intensity.level).reduce(max);
            
            return _buildDayCell(date, intensity, memories.isNotEmpty);
          },
        ),
      ],
    ),
  );
}

4.2 日期单元格

每个日期单元格的颜色根据记忆强度确定:

dart 复制代码
Widget _buildDayCell(DateTime date, MemoryIntensity intensity, bool hasMemory) {
  final isSelected = _selectedDate == date;
  final isToday = date == DateTime.now();

  return GestureDetector(
    onTap: () {
      setState(() {
        _selectedDate = date;
      });
    },
    onLongPress: () {
      _showAddMemoryDialog(date);
    },
    child: Container(
      decoration: BoxDecoration(
        color: intensity.color,  // 根据强度设置颜色
        borderRadius: BorderRadius.circular(8),
        border: Border.all(
          color: isSelected ? Color(0xFFFF6B6B) : Colors.transparent,
        ),
      ),
      child: Stack(
        children: [
          Center(
            child: Text(
              '${date.day}',
              style: TextStyle(
                color: hasMemory ? Colors.white : Colors.black87,
              ),
            ),
          ),
          // 记忆指示点
          if (hasMemory)
            Positioned(
              top: 2,
              right: 2,
              child: Container(
                width: 6,
                height: 6,
                decoration: BoxDecoration(
                  color: Colors.white.withValues(alpha: 0.8),
                  shape: BoxShape.circle,
                ),
              ),
            ),
        ],
      ),
    ),
  );
}

4.3 记忆强度枚举

定义五级记忆强度:

dart 复制代码
enum MemoryIntensity {
  none('', Colors.transparent, 0),
  low('淡忘', Color(0xFFFFE5E5), 1),
  medium('记得', Color(0xFFFFB3B3), 2),
  high('清晰', Color(0xFFFF8080), 3),
  intense('深刻', Color(0xFFFF4D4D), 4),
  unforgettable('难忘', Color(0xFFFF0000), 5);

  final String label;
  final Color color;
  final int level;

  const MemoryIntensity(this.label, this.color, this.level);
}

4.4 记忆添加对话框

添加记忆的对话框:

dart 复制代码
void _showAddMemoryDialog(DateTime date) {
  final titleController = TextEditingController();
  MemoryIntensity selectedIntensity = MemoryIntensity.medium;
  List<String> selectedTags = [];
  String? selectedEmoji;

  showDialog(
    context: context,
    builder: (context) => StatefulBuilder(
      builder: (context, setState) {
        return AlertDialog(
          title: Text('添加记忆 - ${date.month}月${date.day}日'),
          content: Column(
            children: [
              // 标题输入
              TextField(
                controller: titleController,
                decoration: InputDecoration(labelText: '标题'),
              ),
              // 强度选择
              Wrap(
                children: MemoryIntensity.values.skip(1).map((intensity) {
                  return GestureDetector(
                    onTap: () {
                      setState(() {
                        selectedIntensity = intensity;
                      });
                    },
                    child: Container(
                      decoration: BoxDecoration(
                        color: intensity == selectedIntensity
                            ? intensity.color
                            : intensity.color.withValues(alpha: 0.2),
                      ),
                      child: Text(intensity.label),
                    ),
                  );
                }).toList(),
              ),
              // 标签选择
              Wrap(
                children: ['生活', '工作', '家庭'].map((tag) {
                  return FilterChip(
                    label: Text(tag),
                    selected: selectedTags.contains(tag),
                    onSelected: (selected) {
                      setState(() {
                        if (selected) {
                          selectedTags.add(tag);
                        } else {
                          selectedTags.remove(tag);
                        }
                      });
                    },
                  );
                }).toList(),
              ),
            ],
          ),
          actions: [
            TextButton(
              onPressed: () => Navigator.pop(context),
              child: Text('取消'),
            ),
            ElevatedButton(
              onPressed: () {
                _addMemory(
                  date,
                  titleController.text,
                  selectedIntensity,
                  null,
                  selectedTags,
                  selectedEmoji,
                );
                Navigator.pop(context);
              },
              child: Text('保存'),
            ),
          ],
        );
      },
    ),
  );
}

4.5 记忆存储

记忆数据的存储和索引:

dart 复制代码
void _addMemory(DateTime date, String title, MemoryIntensity intensity,
    String? description, List<String> tags, String? emoji) {
  final memory = Memory(
    id: DateTime.now().millisecondsSinceEpoch.toString(),
    date: date,
    title: title,
    description: description,
    intensity: intensity,
    tags: tags,
    emoji: emoji,
    createdAt: DateTime.now(),
  );

  setState(() {
    _memories.add(memory);
    // 建立日期索引
    final key = DateTime(date.year, date.month, date.day);
    _memoryMap[key] = [...(_memoryMap[key] ?? []), memory];
  });
}

五、UI设计规范

5.1 配色方案

应用采用红色为主色调:

颜色类型 色值 用途
主色 #FF6B6B 导航、按钮、强调
辅助色 #FF8E8E 渐变、次要元素
淡忘 #FFE5E5 一级记忆
记得 #FFB3B3 二级记忆
清晰 #FF8080 三级记忆
深刻 #FF4D4D 四级记忆
难忘 #FF0000 五级记忆

5.2 字体规范

元素 字号 字重 颜色
页面标题 28px Bold #FFFFFF
月份标题 20px Bold #000000
日期数字 14px Medium 动态颜色
记忆标题 16px Bold #000000
标签文字 11-12px Regular #000000

5.3 组件规范

5.3.1 热力图日历
复制代码
┌─────────────────────────────────────┐
│  日  一  二  三  四  五  六         │
│                                     │
│      1   2   3   4   5   6         │
│  7   8   9  10  11  12  13         │
│ 14  15  16  17  18  19  20         │
│ 21  22  23  24  25  26  27         │
│ 28  29  30                         │
└─────────────────────────────────────┘
5.3.2 记忆卡片
复制代码
┌─────────────────────────────────────────┐
│  😊  美好的一天              [记得]     │
│      3月15日                            │
│      [生活] [朋友] [美食]               │
└─────────────────────────────────────────┘
5.3.3 强度图例
复制代码
┌──────────────────────────────────┐
│  记忆强度                        │
│                                  │
│  □ 淡忘  □ 记得  □ 清晰         │
│  □ 深刻  □ 难忘                  │
└──────────────────────────────────┘

六、交互设计

6.1 热力图交互

点击日期
长按日期
滑动
用户操作
操作类型
显示记忆详情
打开添加对话框
切换月份
查看记忆列表
点击记忆
查看详情
填写表单
保存记忆
更新热力图

6.2 记忆添加流程

表单 对话框 日历 用户 表单 对话框 日历 用户 长按日期 打开对话框 输入标题 选择强度 添加标签 选择表情 点击保存 返回数据 更新热力图

6.3 页面切换状态

点击时间线Tab
点击统计Tab
点击热力图Tab
点击统计Tab
点击热力图Tab
点击时间线Tab
热力图页
时间线页
统计页


七、数据分析

7.1 统计指标

统计项 计算方式 说明
总记忆数 memories.length 所有记忆数量
本周记忆 最近7天的记忆数 近期活跃度
本月记忆 本月的记忆数 月度活跃度
平均强度 所有记忆强度的平均值 记忆质量

7.2 强度分布分析

dart 复制代码
Map<MemoryIntensity, int> _calculateIntensityCounts() {
  final counts = <MemoryIntensity, int>{};
  
  for (var memory in _memories) {
    counts[memory.intensity] = (counts[memory.intensity] ?? 0) + 1;
  }
  
  return counts;
}

7.3 标签分布分析

dart 复制代码
Map<String, int> _calculateTagCounts() {
  final counts = <String, int>{};
  
  for (var memory in _memories) {
    for (var tag in memory.tags) {
      counts[tag] = (counts[tag] ?? 0) + 1;
    }
  }
  
  return counts;
}

7.4 时间分布分析

时间段 分析维度 应用价值
按周 周记忆数量 了解每周记忆频率
按月 月记忆分布 了解月度记忆模式
按季度 季度记忆趋势 了解长期记忆趋势
按年 年度记忆总结 了解年度记忆概况

八、扩展功能规划

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 热力图日历 记忆记录 时间线展示 统计分析 照片附件 提醒功能 分享功能 云端同步 AI记忆分析 社区分享 V1.0 基础版本 V1.1 增强版本 V1.2 进阶版本 记忆热力图开发计划

8.2 功能扩展建议

8.2.1 照片附件

支持为记忆添加照片:

  • 拍照或选择照片
  • 照片压缩和存储
  • 照片预览和查看
  • 照片数量限制
8.2.2 提醒功能

记忆提醒系统:

  • 周年提醒
  • 定期提醒
  • 自定义提醒
  • 通知推送
8.2.3 AI记忆分析

人工智能记忆分析:

  • 记忆情感分析
  • 记忆主题识别
  • 记忆关联推荐
  • 记忆趋势预测

九、注意事项

9.1 开发注意事项

  1. 日期处理:注意DateTime的比较和索引

  2. 状态管理:使用setState管理本地状态

  3. 性能优化:大量记忆时注意性能

  4. 用户体验:保持界面简洁,避免信息过载

9.2 常见问题

问题 原因 解决方案
热力图不显示 数据为空 检查_memories
颜色不正确 强度映射错误 检查MemoryIntensity
记忆不显示 日期索引错误 检查_memoryMap
对话框不关闭 Navigator未调用 检查pop操作

9.3 使用提示

🧠 记忆热力图使用小贴士 🧠

每一天都值得被记住。

记录生活中的美好瞬间。

热力图越红,记忆越深刻。

长按日期快速添加记忆。

提示:建议每天记录至少一条记忆,让热力图更加丰富。


十、运行说明

10.1 环境要求

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

10.2 运行命令

bash 复制代码
# 查看可用设备
flutter devices

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

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

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

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

十一、总结

记忆热力图是一款独特的记忆管理应用,通过热力图的形式在日历上展示哪些日子值得记住。应用借鉴了GitHub贡献图的视觉设计,将抽象的记忆数据转化为直观的热力图,让用户能够一目了然地看到自己的记忆分布。

从技术实现来看,应用使用GridView构建日历网格,通过颜色编码表示记忆强度,使用Map建立日期索引快速查找记忆,实现了完整的记忆记录和管理系统。

从用户体验来看,应用提供直观的热力图展示,让用户能够快速了解记忆分布。通过长按日期快速添加记忆,点击日期查看详情,操作简单直观。五级记忆强度让用户能够区分记忆的重要程度。

应用不仅是一个记忆记录工具,更是一个生活记录平台。它提醒我们:每一天都值得被记住;记录生活中的美好瞬间;热力图越红,记忆越深刻;长按日期快速添加记忆。在快节奏的现代生活中,记忆热力图为我们提供了一种记录和回顾生活的方式。

记录值得记住的每一天


相关推荐
2301_822703202 小时前
Flutter 框架跨平台鸿蒙开发 - 创意声音合成器应用
算法·flutter·华为·harmonyos·鸿蒙
恋猫de小郭2 小时前
Android 上为什么主题字体对 Flutter 不生效,对 Compose 生效?Flutter 中文字体问题修复
android·前端·flutter
李李李勃谦3 小时前
Flutter 框架跨平台鸿蒙开发 - 创意灵感收集
android·flutter·harmonyos
空中海3 小时前
2.7 列表与滚动性能优化
flutter·性能优化·dart
2301_822703204 小时前
Flutter 框架跨平台鸿蒙开发 - 气味记忆唤醒应用
flutter·华为·开源·harmonyos·鸿蒙
空中海4 小时前
2.4 绘制与动画
flutter·dart
空中海4 小时前
2.6 表单与输入处理
flutter·dart
AI_零食5 小时前
开源鸿蒙跨平台Flutter开发:脑筋急转弯应用开发文档
flutter·华为·开源·harmonyos·鸿蒙
不爱吃糖的程序媛5 小时前
深入理解鸿蒙PC 三方库构建系统中的HPKCHECK文件
华为·harmonyos