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

一、项目概述

运行效果图

image-20260407231309563

image-20260407231317148

image-20260407231322280

image-20260407231326749

1.1 应用简介

思维录音机是一款独特的意识流记录工具,灵感来源于"意识流写作"理念。应用模拟录音机的工作方式,真实记录你的每一个思维片段,不做任何编辑和修饰。就像录音机忠实地记录声音一样,思维录音机忠实地记录你的思维流动。

应用以深紫色为主色调,营造宁静、深邃的思维空间。涵盖录制控制、思维记录、回放浏览、统计分析四大模块,支持8种思维类型分类,通过时间轴和可视化图表帮助用户了解自己的思维模式。

1.2 核心功能

功能模块 功能描述 实现方式
录制控制 开始/暂停/停止录制 状态机 + Timer
思维输入 记录思维内容 TextField + 类型选择
实时显示 意识流实时展示 ListView + 自动滚动
记录管理 浏览历史记录 列表展示 + 详情页
统计分析 思维数据分析 图表可视化
时间追踪 记录时间戳 Duration计算

1.3 录制状态定义

序号 状态名称 Emoji 描述
1 空闲 ⏸️ 等待开始录制
2 录制中 🔴 正在记录思维
3 已暂停 ⏯️ 暂停录制状态

1.4 思维类型定义

序号 类型名称 Emoji 主题色 描述
1 灵感 💡 #FFB74D 突然的想法和创意
2 疑问 #64B5F6 需要思考的问题
3 情绪 💭 #BA68C8 当下的情感状态
4 回忆 📷 #4DB6AC 过去的记忆片段
5 观察 👁️ #81C784 对周围事物的感知
6 反思 🤔 #F06292 对事物的思考
7 想象 #FFD54F 天马行空的幻想
8 担忧 😰 #E57373 焦虑和担心

1.5 技术栈

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

1.6 项目结构

lib/
└── main_thought_recorder.dart
    ├── ThoughtRecorderApp         # 应用入口
    ├── RecordingState             # 录制状态枚举
    ├── ThoughtType                # 思维类型枚举
    ├── Thought                    # 思维数据模型
    ├── RecordingSession           # 录制会话模型
    ├── ThoughtRecorderHomePage    # 主页面(底部导航)
    ├── _buildRecordingPage        # 录制页面
    ├── _buildSessionsPage         # 记录列表页面
    ├── _buildStatsPage            # 统计分析页面
    ├── SessionDetailPage          # 会话详情页面
    ├── WavePainter                # 波形绘制器
    └── TimelineChartPainter       # 时间轴图表绘制器

二、系统架构

2.1 整体架构图

Data Layer

Presentation Layer

主页面
ThoughtRecorderHomePage

录制页面

记录列表

统计分析

录制控制

思维输入

意识流展示

状态管理

计时器

动画效果

类型选择

内容输入

实时列表

自动滚动

会话列表

会话详情

概览统计

类型分布

时间图表

Thought
思维模型

RecordingSession
会话模型

ThoughtType
思维类型

RecordingState
录制状态

2.2 类图设计

manages

manages

uses

displays

contains

has

ThoughtRecorderApp

+Widget build()

«enumeration»

RecordingState

+String label

+String description

+idle()

+recording()

+paused()

«enumeration»

ThoughtType

+String label

+String emoji

+Color color

+idea()

+question()

+emotion()

+memory()

+observation()

+reflection()

+dream()

+worry()

Thought

+String id

+String content

+ThoughtType type

+DateTime timestamp

+Duration relativeTime

+String? note

RecordingSession

+String id

+String title

+DateTime startTime

+DateTime? endTime

+List<Thought> thoughts

+Duration totalDuration

+int thoughtCount

ThoughtRecorderHomePage

-int _selectedIndex

-RecordingState _recordingState

-List<RecordingSession> _sessions

-List<Thought> _currentThoughts

-Timer _durationTimer

-AnimationController _pulseController

-AnimationController _waveController

+Widget build()

-_startRecording()

-_stopRecording()

-_addThought()

SessionDetailPage

+RecordingSession session

+Widget build()

2.3 页面导航流程

录制

记录

统计

应用启动

录制页面

底部导航

录制控制

会话列表

统计分析

开始录制

输入思维

添加到意识流

继续?

停止录制

保存会话

查看会话

会话详情

浏览意识流

查看概览

类型分布

时间图表

2.4 录制流程

数据层 状态管理 录制页面 用户 数据层 状态管理 录制页面 用户 loop [录制过程] 点击录制按钮 更新状态为recording 启动计时器 输入思维 创建Thought对象 添加到列表 显示思维 点击停止按钮 更新状态为idle 创建RecordingSession 保存会话 显示成功提示

三、核心模块设计

3.1 数据模型设计

3.1.1 录制状态枚举 (RecordingState)
enum RecordingState {
  idle('空闲', '点击开始录制你的思维'),
  recording('录制中', '正在记录你的意识流...'),
  paused('已暂停', '点击继续录制');

  final String label;
  final String description;

  const RecordingState(this.label, this.description);
}
3.1.2 思维类型枚举 (ThoughtType)
enum ThoughtType {
  idea('灵感', '💡', Color(0xFFFFB74D)),
  question('疑问', '❓', Color(0xFF64B5F6)),
  emotion('情绪', '💭', Color(0xFFBA68C8)),
  memory('回忆', '📷', Color(0xFF4DB6AC)),
  observation('观察', '👁️', Color(0xFF81C784)),
  reflection('反思', '🤔', Color(0xFFF06292)),
  dream('想象', '✨', Color(0xFFFFD54F)),
  worry('担忧', '😰', Color(0xFFE57373));

  final String label;
  final String emoji;
  final Color color;

  const ThoughtType(this.label, this.emoji, this.color);
}
3.1.3 思维模型 (Thought)
class Thought {
  final String id;              // 唯一标识
  final String content;         // 思维内容
  final ThoughtType type;       // 思维类型
  final DateTime timestamp;     // 时间戳
  final Duration relativeTime;  // 相对时间
  final String? note;           // 备注
}
3.1.4 录制会话模型 (RecordingSession)
class RecordingSession {
  final String id;                    // 唯一标识
  final String title;                 // 会话标题
  final DateTime startTime;           // 开始时间
  final DateTime? endTime;            // 结束时间
  final List<Thought> thoughts;       // 思维列表
  final Duration totalDuration;       // 总时长
  int get thoughtCount => thoughts.length;
}
3.1.5 思维类型分布
19% 16% 15% 13% 12% 11% 8% 7% 思维类型分布示例 灵感 疑问 情绪 回忆 观察 反思 想象 担忧

3.2 页面结构设计

3.2.1 主页面布局

ThoughtRecorderHomePage

IndexedStack

录制页面

记录列表

统计分析

NavigationBar

录制 Tab

记录 Tab

统计 Tab

3.2.2 录制页面结构

录制页面

SliverAppBar

录制控制

思维输入

意识流展示

标题

波形动画

录制按钮

计时器

状态提示

类型选择

内容输入

发送按钮

思维列表

自动滚动

3.2.3 录制控制结构

录制控制

圆形按钮

计时显示

状态描述

空闲态: 录制图标

录制态: 停止图标

暂停态: 播放图标

脉冲动画

录制时放大缩小

红色背景闪烁

时:分:秒格式

实时更新

3.2.4 会话详情页面结构

会话详情

会话信息

意识流列表

时长

思维数

日期

思维卡片

类型标签

时间戳

内容

3.3 录制状态机

应用启动

点击录制

点击停止

点击暂停

点击继续

点击停止

空闲状态

录制中

已暂停

计时器运行
可输入思维

计时器暂停
不可输入

3.4 时间追踪流程

开始录制

记录开始时间

启动计时器

每秒更新

计算当前时长

更新UI显示

继续录制?

停止计时器

计算总时长

保存会话

添加思维

记录时间戳

计算相对时间

保存到Thought


四、UI设计规范

4.1 配色方案

应用以深紫色为主色调,营造宁静、深邃的思维空间:

颜色类型 色值 用途
主色 #5C6BC0 (Indigo 400) 导航、强调元素
录制红 #E53935 录制状态指示
灵感色 #FFB74D 灵感类型
疑问色 #64B5F6 疑问类型
情绪色 #BA68C8 情绪类型
回忆色 #4DB6AC 回忆类型
观察色 #81C784 观察类型
反思色 #F06292 反思类型
想象色 #FFD54F 想象类型
担忧色 #E57373 担忧类型

4.2 状态配色

状态 色值 视觉效果
空闲 主色 平静蓝色
录制中 红色 脉冲动画
已暂停 橙色 静态显示

4.3 字体规范

元素 字号 字重 颜色
页面标题 24px Bold 主色
计时器 36px Bold 黑色
思维内容 14px Regular 黑色
类型标签 10px Medium 类型色
时间戳 10px Regular 灰色

4.4 组件规范

4.4.1 录制控制组件
┌─────────────────────────────────────┐
│                                     │
│         ┌─────────────┐             │
│         │             │             │
│         │      ●      │             │
│         │             │             │
│         └─────────────┘             │
│                                     │
│            05:32                    │
│        正在记录你的意识流...         │
│                                     │
│            [暂停]                   │
│                                     │
└─────────────────────────────────────┘

● = 录制按钮(红色脉冲动画)
4.4.2 思维输入组件
┌─────────────────────────────────────────────┐
│ 记录思维                          第 5 条  │
│                                             │
│ [💡灵感] [❓疑问] [💭情绪] [📷回忆] ...    │
│                                             │
│ ┌─────────────────────────────────────────┐ │
│ │ 记录你此刻的思维...                    │ │
│ │                                         │ │
│ │                                         │ │
│ │                                   [➤]  │ │
│ └─────────────────────────────────────────┘ │
└─────────────────────────────────────────────┘
4.4.3 思维卡片
┌─────────────────────────────────────────────┐
│ ┌────┐  [💡灵感]  00:15                     │
│ │ 💡 │                                        │
│ └────┘  今天的天空特别蓝,突然想到了         │
│         一个关于颜色的新想法                 │
└─────────────────────────────────────────────┘
4.4.4 会话卡片
┌─────────────────────────────────────────────┐
│ ┌────┐  思维记录 1                05:32    │
│ │ 🧠 │                                  8条思维│
│ └────┘  2天前                             │
│                                             │
│  [💡3] [❓2] [💭2] [👁️1]                  │
└─────────────────────────────────────────────┘
4.4.5 统计卡片
┌─────────────────────────────────────────────┐
│            概览                             │
│                                             │
│  ┌──────┐  ┌──────┐  ┌──────┐            │
│  │ 📝   │  │ 🧠   │  │ ⏱️   │            │
│  │  15  │  │  87  │  │ 45分钟│            │
│  │记录次数│  │思维总数│  │ 总时长 │            │
│  └──────┘  └──────┘  └──────┘            │
└─────────────────────────────────────────────┘

五、核心功能实现

5.1 录制控制实现

void _startRecording() {
  setState(() {
    _recordingState = RecordingState.recording;
    _recordingStartTime = DateTime.now();
    _currentDuration = Duration.zero;
    _currentThoughts.clear();
  });

  _durationTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
    if (mounted) {
      setState(() {
        _currentDuration = DateTime.now().difference(_recordingStartTime!);
      });
    }
  });
}

void _stopRecording() {
  _durationTimer?.cancel();

  if (_currentThoughts.isEmpty) {
    setState(() {
      _recordingState = RecordingState.idle;
    });
    return;
  }

  final session = RecordingSession(
    id: DateTime.now().millisecondsSinceEpoch.toString(),
    title: '思维记录 ${_sessions.length + 1}',
    startTime: _recordingStartTime!,
    endTime: DateTime.now(),
    thoughts: List.from(_currentThoughts),
    totalDuration: _currentDuration,
  );

  setState(() {
    _sessions.insert(0, session);
    _recordingState = RecordingState.idle;
    _currentThoughts.clear();
  });
}

5.2 思维添加实现

void _addThought() {
  if (_thoughtController.text.trim().isEmpty) return;

  final thought = Thought(
    id: DateTime.now().millisecondsSinceEpoch.toString(),
    content: _thoughtController.text.trim(),
    type: _selectedType,
    timestamp: DateTime.now(),
    relativeTime: _currentDuration,
  );

  setState(() {
    _currentThoughts.add(thought);
    _thoughtController.clear();
  });

  // 自动滚动到底部
  Future.delayed(const Duration(milliseconds: 100), () {
    if (_scrollController.hasClients) {
      _scrollController.animateTo(
        _scrollController.position.maxScrollExtent,
        duration: const Duration(milliseconds: 300),
        curve: Curves.easeOut,
      );
    }
  });
}

5.3 脉冲动画实现


void initState() {
  super.initState();
  _pulseController = AnimationController(
    vsync: this,
    duration: const Duration(milliseconds: 1500),
  )..repeat(reverse: true);
}

Widget _buildRecordingControl() {
  return AnimatedBuilder(
    animation: _pulseController,
    builder: (context, child) {
      return Container(
        width: 120 + (_recordingState == RecordingState.recording 
            ? _pulseController.value * 10 : 0),
        height: 120 + (_recordingState == RecordingState.recording 
            ? _pulseController.value * 10 : 0),
        decoration: BoxDecoration(
          shape: BoxShape.circle,
          color: _recordingState == RecordingState.recording
              ? Colors.red.withValues(alpha: 0.2 + _pulseController.value * 0.3)
              : Theme.of(context).colorScheme.primaryContainer,
        ),
        child: IconButton(
          icon: Icon(_recordingState == RecordingState.recording
              ? Icons.stop
              : Icons.fiber_manual_record),
          onPressed: () {
            if (_recordingState == RecordingState.idle) {
              _startRecording();
            } else if (_recordingState == RecordingState.recording) {
              _stopRecording();
            }
          },
        ),
      );
    },
  );
}

5.4 时间格式化

String _formatDuration(Duration duration) {
  final hours = duration.inHours;
  final minutes = duration.inMinutes.remainder(60);
  final seconds = duration.inSeconds.remainder(60);

  if (hours > 0) {
    return '${hours.toString().padLeft(2, '0')}:'
           '${minutes.toString().padLeft(2, '0')}:'
           '${seconds.toString().padLeft(2, '0')}';
  }
  return '${minutes.toString().padLeft(2, '0')}:'
         '${seconds.toString().padLeft(2, '0')}';
}

5.5 波形动画实现

class WavePainter extends CustomPainter {
  final double animation;
  final Color color;

  WavePainter({required this.animation, required this.color});

  
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = color
      ..style = PaintingStyle.stroke
      ..strokeWidth = 2;

    final path = Path();
    final waveWidth = size.width / 4;

    for (var i = 0; i < 4; i++) {
      final x = i * waveWidth;
      final y = size.height / 2 + sin((animation * 2 * pi) + i * pi / 2) * 20;

      if (i == 0) {
        path.moveTo(x, y);
      } else {
        path.lineTo(x, y);
      }
    }

    canvas.drawPath(path, paint);
  }

  
  bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}

六、交互设计

6.1 录制流程

思维列表 计时器 录制页面 用户 思维列表 计时器 录制页面 用户 loop [录制过程] 点击录制按钮 启动计时 显示录制状态 输入思维 添加思维 显示思维 更新计时 点击停止 停止计时 保存会话

6.2 思维输入流程

开始输入

选择思维类型

输入思维内容

内容非空?

创建Thought对象

提示输入内容

添加到列表

清空输入框

滚动到底部

继续输入

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 开发注意事项

  1. 计时器管理:Timer需要在dispose时取消,避免内存泄漏

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

  3. 状态同步:录制状态变化时需要同步更新UI

  4. 自动滚动:添加思维后需要自动滚动到底部

  5. 数据持久化:会话数据需要本地存储

8.2 常见问题

问题 原因 解决方案
计时器不停止 未正确取消 在dispose中取消
动画卡顿 Controller未释放 在dispose中释放
滚动失效 Controller未初始化 检查ScrollController
状态不同步 未调用setState 确保状态更新

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_thought_recorder.dart --web-port 8121

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

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

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

十、总结

思维录音机通过录制控制、思维记录、回放浏览、统计分析四大模块,为用户提供了一个独特的意识流记录平台。应用采用"不做编辑"的理念,真实记录每一个思维片段,帮助用户了解自己的思维模式。

核心功能涵盖录制控制、思维输入、实时展示、会话管理、统计分析五大模块。录制控制系统通过状态机和计时器实现精确控制;思维输入支持8种类型分类和实时添加;实时展示通过自动滚动保持最新思维可见;会话管理提供完整的记录浏览和详情查看;统计分析通过图表可视化展示思维分布和趋势。

应用采用Material Design 3设计规范,以深紫色为主色调,营造宁静、深邃的思维空间。通过本应用,希望能够帮助用户记录意识流,发现真实的自己。

记录你的意识流,不做任何编辑


Logo

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

更多推荐