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

一、项目概述

运行效果图

image-20260405112931432

image-20260405112936614

image-20260405112942560

image-20260405112952042

image-20260405112958207

1.1 应用简介

心情日记是一款专注于情感记录与追踪的移动应用,为用户提供一个私密、便捷的空间记录每日心情变化。在快节奏的现代生活中,人们常常忽略了对自身情绪的关注与觉察,本应用帮助用户追踪情绪轨迹,从而更好地了解自己、关爱自己。

应用支持八种心情类型选择,配以表情符号与主题色彩,让情绪表达更加直观生动。日记撰写支持标题、内容、日期、地点、天气等全方位记录,标签管理功能让日记分类更加灵活。心情统计功能可视化展示各心情占比,帮助用户洞察情绪规律。

1.2 核心功能

功能模块 功能描述 实现方式
心情选择 八种心情类型,配以表情符号与主题色彩 GridView选择器
日记撰写 标题、内容、日期、地点、天气全方位记录 表单页面
标签管理 自定义标签,灵活分类日记内容 Chip组件
搜索筛选 按关键词、心情类型快速定位日记 TextField过滤
心情统计 可视化展示各心情占比,洞察情绪规律 AlertDialog + 进度条
日记详情 沉浸式阅读体验,完整展示日记信息 详情页面
日记编辑 修改已有日记内容 表单预填充
日记删除 删除不需要的记录 确认对话框

1.3 日记记录字段

字段 类型 说明
日记ID String 唯一标识,时间戳生成
日记标题 String 日记名称,必填
日记内容 String 日记正文,必填
心情类型 MoodType 八种心情枚举
日记日期 DateTime 日记记录日期
标签列表 List 分类标签
地点 String 记录地点
天气 String 当日天气
创建时间 DateTime 记录创建时间
更新时间 DateTime 最后修改时间

1.4 技术栈

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

1.5 项目结构

lib/
└── main_mood_diary.dart
    ├── MoodDiaryApp           # 应用入口
    ├── MoodType               # 心情类型枚举
    ├── MoodDiary              # 日记数据模型
    ├── MoodDiaryPage          # 主列表页面
    │   ├── _buildMoodSummary()    # 心情概览卡片
    │   ├── _buildSearchBar()      # 搜索栏
    │   ├── _buildDiariesList()    # 日记列表
    │   ├── _buildDiaryCard()      # 日记卡片
    │   └── _showStatistics()      # 统计对话框
    ├── MoodDiaryEditPage      # 编辑页面
    │   ├── _selectDate()          # 日期选择
    │   ├── _addTag()              # 添加标签
    │   └── _save()                # 保存日记
    └── MoodDiaryDetailPage    # 详情页面

二、系统架构

2.1 整体架构图

Data Layer

Business Logic

Presentation Layer

列表页面

心情概览卡片

搜索栏

日记卡片列表

编辑页面

心情选择器

表单输入区

标签管理区

详情页面

心情展示区

内容展示区

日记管理
增删改查

心情统计
占比计算

筛选搜索
_filteredDiaries

今日心情
计算逻辑

MoodDiary
日记模型

MoodType
心情枚举

2.2 类图设计

contains

manages

has

navigates

navigates

MoodDiaryApp

+Widget build()

«enumeration»

MoodType

happy

sad

angry

anxious

calm

excited

tired

grateful

MoodDiary

+String id

+String title

+String content

+MoodType mood

+DateTime date

+List<String> tags

+String location

+String weather

+DateTime createdAt

+DateTime updatedAt

+String moodText

+String moodEmoji

+Color moodColor

MoodDiaryPage

-List<MoodDiary> _diaries

-String _searchQuery

-MoodType? _selectedMood

-List<MoodDiary> _filteredDiaries

-Map<MoodType,int> _moodStats

+Widget build()

-void _addDiary()

-void _editDiary()

-void _deleteDiary()

MoodDiaryEditPage

-MoodDiary? diary

-TextEditingController _titleController

-TextEditingController _contentController

-MoodType _selectedMood

-List<String> _tags

+void _save()

+void _addTag()

+void _selectDate()

MoodDiaryDetailPage

+MoodDiary diary

+Widget build()

2.3 数据流程图

新建

编辑

删除

查看

搜索

筛选

统计

用户操作

操作类型

打开编辑页面

打开编辑页面-预填充

确认对话框

打开详情页面

过滤日记列表

按心情过滤

显示统计对话框

选择心情

填写内容

添加标签/地点/天气

保存日记

更新日记列表

计算各心情数量

计算占比百分比

显示统计结果

2.4 心情统计流程

数据模型 统计对话框 主页面 用户 数据模型 统计对话框 主页面 用户 点击统计按钮 获取所有日记 返回日记列表 遍历心情类型 计算各心情数量 计算占比百分比 显示统计结果 展示进度条图表

三、核心模块设计

3.1 数据模型设计

3.1.1 心情类型枚举 (MoodType)
enum MoodType {
  happy,    // 开心
  sad,      // 难过
  angry,    // 愤怒
  anxious,  // 焦虑
  calm,     // 平静
  excited,  // 兴奋
  tired,    // 疲惫
  grateful, // 感恩
}
3.1.2 心情属性映射
心情类型 中文名称 表情符号 主题颜色
happy 开心 😊 黄色
sad 难过 😢 蓝色
angry 愤怒 😠 红色
anxious 焦虑 😰 紫色
calm 平静 😌 绿色
excited 兴奋 🤩 橙色
tired 疲惫 😴 灰色
grateful 感恩 🙏 粉色
3.1.3 日记模型 (MoodDiary)
class MoodDiary {
  final String id;                  // 唯一标识
  String title;                     // 日记标题
  String content;                   // 日记内容
  MoodType mood;                    // 心情类型
  DateTime date;                    // 日记日期
  List<String> tags;                // 标签列表
  String location;                  // 地点
  String weather;                   // 天气
  DateTime createdAt;               // 创建时间
  DateTime updatedAt;               // 更新时间

  MoodDiary({
    required this.id,
    required this.title,
    required this.content,
    required this.mood,
    required this.date,
    this.tags = const [],
    this.location = '',
    this.weather = '',
    required this.createdAt,
    required this.updatedAt,
  });

  String get moodText;    // 心情中文名称
  String get moodEmoji;   // 心情表情符号
  Color get moodColor;    // 心情主题颜色
}

3.2 筛选过滤算法

3.2.1 过滤流程

获取全部日记

是否选择心情?

按心情类型过滤

是否有搜索词?

关键词匹配过滤

按日期排序

返回过滤结果

3.2.2 过滤实现
List<MoodDiary> get _filteredDiaries {
  var diaries = _diaries.toList();

  // 心情类型过滤
  if (_selectedMood != null) {
    diaries = diaries.where((d) => d.mood == _selectedMood).toList();
  }

  // 关键词搜索
  if (_searchQuery.isNotEmpty) {
    diaries = diaries.where((d) {
      return d.title.toLowerCase().contains(_searchQuery.toLowerCase()) ||
          d.content.toLowerCase().contains(_searchQuery.toLowerCase()) ||
          d.tags.any((tag) =>
              tag.toLowerCase().contains(_searchQuery.toLowerCase()));
    }).toList();
  }

  // 按日期倒序排列
  diaries.sort((a, b) => b.date.compareTo(a.date));
  return diaries;
}

3.3 心情统计算法

3.3.1 统计流程

遍历心情类型

统计该心情日记数量

计算总数

计算占比百分比

生成进度条数据

3.3.2 统计实现
Map<MoodType, int> get _moodStats {
  final stats = <MoodType, int>{};
  for (var mood in MoodType.values) {
    stats[mood] = _diaries.where((d) => d.mood == mood).length;
  }
  return stats;
}

// 在统计对话框中计算百分比
final count = stats[mood] ?? 0;
final total = _diaries.length;
final percentage = total > 0
    ? (count / total * 100).toStringAsFixed(1)
    : '0.0';

3.4 今日心情计算

3.4.1 计算流程

获取今日日期

筛选今日日记

今日是否有日记?

统计各心情出现次数

返回null

找出出现最多的心情

返回今日心情

3.4.2 计算实现
Widget _buildMoodSummary() {
  final today = DateTime.now();
  final todayDiaries = _diaries
      .where((d) =>
          d.date.year == today.year &&
          d.date.month == today.month &&
          d.date.day == today.day)
      .toList();

  MoodType? todayMood;
  if (todayDiaries.isNotEmpty) {
    final moodCounts = <MoodType, int>{};
    for (var d in todayDiaries) {
      moodCounts[d.mood] = (moodCounts[d.mood] ?? 0) + 1;
    }
    todayMood = moodCounts.entries
        .reduce((a, b) => a.value > b.value ? a : b)
        .key;
  }
  // ...
}

3.5 页面结构设计

3.5.1 列表页面布局

列表页面

AppBar

心情概览卡片

搜索栏

日记卡片列表

浮动按钮

标题: 心情日记

统计按钮

筛选菜单

今日心情图标

今日心情文字

日记总数

日记卡片1

日记卡片2

...

3.5.2 编辑页面布局
┌─────────────────────────────────────────────────────────────┐
│  AppBar: 写日记/编辑日记                          [💾 保存] │
├─────────────────────────────────────────────────────────────┤
│  今天的心情                                                  │
│  ┌────┐ ┌────┐ ┌────┐ ┌────┐ ┌────┐ ┌────┐ ┌────┐ ┌────┐  │
│  │ 😊 │ │ 😢 │ │ 😠 │ │ 😰 │ │ 😌 │ │ 🤩 │ │ 😴 │ │ 🙏 │  │
│  │开心│ │难过│ │愤怒│ │焦虑│ │平静│ │兴奋│ │疲惫│ │感恩│  │
│  └────┘ └────┘ └────┘ └────┘ └────┘ └────┘ └────┘ └────┘  │
│                                                             │
│  📝 日记标题 *                                              │
│  ┌─────────────────────────────────────────────────────┐   │
│  │                                                     │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  📅 日期                                                    │
│  ┌─────────────────────────────────────────────────────┐   │
│  │ 2024-01-15                                          │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  📍 地点                              ☀️ 天气              │
│  ┌──────────────────────┐  ┌──────────────────────┐        │
│  │                      │  │                      │        │
│  └──────────────────────┘  └──────────────────────┘        │
│                                                             │
│  📋 日记内容 *                                              │
│  ┌─────────────────────────────────────────────────────┐   │
│  │              多行文本输入                            │   │
│  │                                                     │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  标签: [朋友] [户外] [×]                                    │
└─────────────────────────────────────────────────────────────┘

3.6 状态管理

3.6.1 核心状态变量
class _MoodDiaryPageState extends State<MoodDiaryPage> {
  final List<MoodDiary> _diaries = [];   // 所有日记
  String _searchQuery = '';               // 搜索关键词
  MoodType? _selectedMood;                // 选中的心情筛选
}

class _MoodDiaryEditPageState extends State<MoodDiaryEditPage> {
  late MoodType _selectedMood;            // 选中的心情
  late DateTime _selectedDate;            // 选中的日期
  late List<String> _tags;                // 标签列表
}
3.6.2 状态更新流程
// 添加日记
void _addDiary() async {
  final result = await Navigator.push<MoodDiary>(
    context,
    MaterialPageRoute(builder: (context) => const MoodDiaryEditPage()),
  );

  if (result != null) {
    setState(() {
      _diaries.insert(0, result);
    });
  }
}

// 删除日记
void _deleteDiary(MoodDiary diary) {
  setState(() {
    _diaries.removeWhere((d) => d.id == diary.id);
  });
}

四、UI设计规范

4.1 配色方案

应用采用粉色主题风格,体现温馨的情感氛围:

颜色类型 色值 用途
主色 Pink AppBar、按钮、强调
开心 Yellow 开心心情标识
难过 Blue 难过心情标识
愤怒 Red 愤怒心情标识
焦虑 Purple 焦虑心情标识
平静 Green 平静心情标识
兴奋 Orange 兴奋心情标识
疲惫 Grey 疲惫心情标识
感恩 Pink 感恩心情标识

4.2 心情类型样式

4.2.1 心情选择器
心情 表情 颜色 选中效果
开心 😊 黄色 黄色背景 + 黄色边框
难过 😢 蓝色 蓝色背景 + 蓝色边框
愤怒 😠 红色 红色背景 + 红色边框
焦虑 😰 紫色 紫色背景 + 紫色边框
平静 😌 绿色 绿色背景 + 绿色边框
兴奋 🤩 橙色 橙色背景 + 橙色边框
疲惫 😴 灰色 灰色背景 + 灰色边框
感恩 🙏 粉色 粉色背景 + 粉色边框
4.2.2 心情卡片图标
┌─────────────────┐
│   😊            │  ← 心情表情
│                 │
│   彩色圆角背景   │  ← 心情对应颜色
└─────────────────┘

4.3 组件规范

4.3.1 日记卡片
┌─────────────────────────────────────────────────────────────┐
│  ┌────┐  美好的一天                                   ⋮      │
│  │ 😊 │  2024-01-15                                          │
│  └────┘                                                      │
│  今天阳光明媚,和朋友一起去了公园野餐。大家聊得很开心...      │
│                                                              │
│  📍 中央公园  ☀️ 晴天  [朋友] [户外]                         │
└─────────────────────────────────────────────────────────────┘
4.3.2 心情概览卡片
┌─────────────────────────────────────────────────────────────┐
│  ┌────┐  今日心情                    ┌────┐                │
│  │ 😊 │  开心                        │ 15 │                │
│  │    │                              │篇日记│               │
│  └────┘                              └────┘                │
└─────────────────────────────────────────────────────────────┘
4.3.3 统计对话框
┌─────────────────────────────────────────┐
│  心情统计                          [×]  │
├─────────────────────────────────────────┤
│  😊 开心      5篇 (33.3%)               │
│  ████████████░░░░░░░░░░░░░░░░░░░░░░░░░  │
│                                         │
│  😢 难过      2篇 (13.3%)               │
│  █████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░  │
│                                         │
│  😌 平静      3篇 (20.0%)               │
│  ████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░  │
│  ...                                    │
├─────────────────────────────────────────┤
│                              [关闭]     │
└─────────────────────────────────────────┘

4.4 交互设计

4.4.1 操作方式
操作 手势 效果
查看详情 点击卡片 跳转详情页
新建日记 点击浮动按钮 跳转编辑页
编辑日记 点击菜单-编辑 跳转编辑页
删除日记 点击菜单-删除 确认后删除
搜索 输入关键词 实时过滤
筛选 点击筛选图标 选择心情类型
统计 点击统计图标 显示统计对话框
4.4.2 心情选择交互
未选中状态:  ┌────────┐
            │   😊   │  灰色背景
            │  开心  │
            └────────┘

选中状态:    ┌────────┐
            │   😊   │  黄色背景 + 黄色边框
            │  开心  │
            └────────┘

五、核心功能实现

5.1 列表页面构建


Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: const Text('心情日记'),
      actions: [
        IconButton(
          icon: const Icon(Icons.bar_chart),
          onPressed: _showStatistics,
        ),
        PopupMenuButton<MoodType?>(
          icon: const Icon(Icons.filter_list),
          onSelected: (value) {
            setState(() {
              _selectedMood = value;
            });
          },
          itemBuilder: (context) => [
            const PopupMenuItem(value: null, child: Text('全部心情')),
            ...MoodType.values.map((mood) => PopupMenuItem(
              value: mood,
              child: Text(moodEmoji + ' ' + moodText),
            )),
          ],
        ),
      ],
    ),
    body: Column(
      children: [
        _buildMoodSummary(),
        _buildSearchBar(),
        Expanded(
          child: _filteredDiaries.isEmpty
              ? _buildEmptyState()
              : _buildDiariesList(),
        ),
      ],
    ),
    floatingActionButton: FloatingActionButton(
      onPressed: _addDiary,
      child: const Icon(Icons.add),
    ),
  );
}

5.2 心情选择器

Wrap(
  spacing: 12,
  runSpacing: 12,
  children: MoodType.values.map((mood) {
    final isSelected = _selectedMood == mood;
    final tempDiary = MoodDiary(
      id: '', title: '', content: '',
      mood: mood, date: DateTime.now(),
      createdAt: DateTime.now(), updatedAt: DateTime.now(),
    );
    return GestureDetector(
      onTap: () {
        setState(() {
          _selectedMood = mood;
        });
      },
      child: Container(
        padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
        decoration: BoxDecoration(
          color: isSelected
              ? tempDiary.moodColor.withValues(alpha: 0.2)
              : Colors.grey.shade100,
          borderRadius: BorderRadius.circular(16),
          border: Border.all(
            color: isSelected ? tempDiary.moodColor : Colors.transparent,
            width: 2,
          ),
        ),
        child: Column(
          children: [
            Text(tempDiary.moodEmoji, style: const TextStyle(fontSize: 28)),
            const SizedBox(height: 4),
            Text(tempDiary.moodText),
          ],
        ),
      ),
    );
  }).toList(),
)

5.3 标签管理

void _addTag() {
  if (_tagController.text.isNotEmpty &&
      !_tags.contains(_tagController.text)) {
    setState(() {
      _tags.add(_tagController.text);
      _tagController.clear();
    });
  }
}

void _removeTag(String tag) {
  setState(() {
    _tags.remove(tag);
  });
}

// 标签显示
Wrap(
  spacing: 8,
  runSpacing: 8,
  children: _tags.map((tag) {
    return Chip(
      label: Text(tag),
      onDeleted: () => _removeTag(tag),
      deleteIcon: const Icon(Icons.close, size: 16),
    );
  }).toList(),
)

5.4 心情统计对话框

void _showStatistics() {
  final stats = _moodStats;
  showDialog(
    context: context,
    builder: (context) {
      return AlertDialog(
        title: const Text('心情统计'),
        content: SizedBox(
          width: 300,
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: MoodType.values.map((mood) {
              final count = stats[mood] ?? 0;
              final total = _diaries.length;
              final percentage = total > 0
                  ? (count / total * 100).toStringAsFixed(1)
                  : '0.0';
              return Row(
                children: [
                  Text(moodEmoji, style: const TextStyle(fontSize: 24)),
                  const SizedBox(width: 8),
                  Expanded(
                    child: Column(
                      children: [
                        Row(
                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
                          children: [
                            Text(moodText),
                            Text('$count篇 ($percentage%)'),
                          ],
                        ),
                        LinearProgressIndicator(
                          value: total > 0 ? count / total : 0,
                          backgroundColor: Colors.grey.shade200,
                          valueColor: AlwaysStoppedAnimation(moodColor),
                        ),
                      ],
                    ),
                  ),
                ],
              );
            }).toList(),
          ),
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context),
            child: const Text('关闭'),
          ),
        ],
      );
    },
  );
}

5.5 表单验证与保存

void _save() {
  if (_formKey.currentState!.validate()) {
    final now = DateTime.now();

    final diary = MoodDiary(
      id: widget.diary?.id ?? DateTime.now().millisecondsSinceEpoch.toString(),
      title: _titleController.text,
      content: _contentController.text,
      mood: _selectedMood,
      date: _selectedDate,
      location: _locationController.text,
      weather: _weatherController.text,
      tags: _tags,
      createdAt: widget.diary?.createdAt ?? now,
      updatedAt: now,
    );

    Navigator.pop(context, diary);
  }
}

六、心情类型知识拓展

6.1 心情分类体系

心情类型

正向情绪

负向情绪

中性情绪

开心 😊

兴奋 🤩

感恩 🙏

难过 😢

愤怒 😠

焦虑 😰

平静 😌

疲惫 😴

6.2 心情与色彩心理学

心情 颜色 心理学含义
开心 黄色 温暖、活力、乐观
难过 蓝色 冷静、深沉、忧郁
愤怒 红色 热情、力量、警示
焦虑 紫色 神秘、敏感、不安
平静 绿色 自然、和谐、安宁
兴奋 橙色 活力、创意、热情
疲惫 灰色 中性、低调、休息
感恩 粉色 温柔、爱意、感激

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 核心记录功能 心情统计功能 搜索筛选功能 数据持久化 心情趋势图 导出功能 提醒功能 密码保护 云同步功能 V1.0 基础版本 V1.1 增强版本 V1.2 进阶版本 心情日记应用开发计划

7.2 功能扩展建议

7.2.1 数据持久化
功能 说明
SQLite存储 本地数据库存储日记
数据备份 支持数据导出备份
数据恢复 支持数据导入恢复
7.2.2 心情趋势分析
功能 说明
折线图 展示心情变化趋势
热力图 展示心情分布密度
月度报告 生成心情分析报告
7.2.3 智能功能
功能 说明
心情提醒 定时提醒记录心情
AI分析 智能情绪识别建议
关联分析 分析心情与天气/地点关联

八、注意事项

8.1 开发注意事项

  1. 心情颜色处理:使用 withValues(alpha:) 替代已废弃的 withOpacity()

  2. 日期格式化:统一使用 yyyy-MM-dd 格式

  3. 表单验证:标题和内容为必填字段

  4. 状态更新:使用 setState 触发界面刷新

8.2 用户体验优化

💡 用户体验建议 💡

  • 心情选择直观便捷
  • 日记记录简洁高效
  • 统计展示清晰明了
  • 搜索筛选快速精准

8.3 常见问题

问题 原因 解决方案
心情颜色不显示 颜色值错误 检查moodColor getter
统计百分比错误 总数为0 添加总数判断
搜索无结果 过滤条件错误 检查过滤逻辑
日期显示异常 格式化错误 统一日期格式

九、运行说明

9.1 环境要求

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

9.2 运行命令

# 查看可用设备
flutter devices

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

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

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

十、总结

心情日记应用通过完善的功能设计,帮助用户记录和管理每日心情。应用支持八种心情类型,配以表情符号与主题色彩,让情绪表达更加直观生动。日记撰写支持标题、内容、日期、地点、天气等全方位记录,标签管理功能让日记分类更加灵活。

心情统计功能可视化展示各心情占比,帮助用户洞察情绪规律。今日心情功能自动计算当天主要心情状态,让用户快速了解当日情绪。搜索和筛选功能让用户快速定位目标日记,提高管理效率。

界面设计采用粉色主题风格,体现温馨的情感氛围。心情选择器采用彩色卡片设计,选中状态清晰明了。应用采用Material Design 3设计规范,遵循Flutter最佳实践,代码结构清晰,易于维护和扩展。

**记录心情,感悟生活,关爱自己,从心开始!
Logo

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

更多推荐