Flutter 框架跨平台鸿蒙开发 - 焦虑粉碎机
运行效果图焦虑粉碎机是一款帮助用户释放心理压力的情绪管理应用。用户可以将内心的烦恼、焦虑写下来,通过"粉碎"动画效果,象征性地将负面情绪消除,达到心理疏导的目的。应用采用"输入-粉碎-记录"的闭环设计,让用户在写下烦恼的过程中梳理情绪,在粉碎动画中获得释放感,在历史记录中回顾自己的成长轨迹。焦虑粉碎机应用通过直观的"写下-粉碎"交互模式,帮助用户释放心理压力。沉浸式动画:50个粒子飞散效果,视觉冲
·
焦虑粉碎机应用
欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net
一、项目概述
运行效果图



1.1 应用简介
焦虑粉碎机是一款帮助用户释放心理压力的情绪管理应用。用户可以将内心的烦恼、焦虑写下来,通过"粉碎"动画效果,象征性地将负面情绪消除,达到心理疏导的目的。
应用采用"输入-粉碎-记录"的闭环设计,让用户在写下烦恼的过程中梳理情绪,在粉碎动画中获得释放感,在历史记录中回顾自己的成长轨迹。
1.2 核心功能
| 功能模块 | 功能描述 | 实现方式 |
|---|---|---|
| 烦恼输入 | 多行文本输入、字数限制 | TextField、maxLength |
| 粉碎动画 | 震动效果 + 粒子飞散 | AnimationController、CustomPainter |
| 历史记录 | 分类展示、状态管理 | SliverList、状态筛选 |
| 记录管理 | 粉碎、删除操作 | 状态更新、列表操作 |
| 统计展示 | 待粉碎/已粉碎数量 | 实时统计卡片 |
1.3 粉碎动画流程
| 阶段 | 时长 | 效果描述 |
|---|---|---|
| 1 | 500ms | 输入框快速震动,模拟蓄力 |
| 2 | 1500ms | 50个彩色粒子飞散,模拟粉碎 |
| 3 | 即时 | 记录状态更新,显示完成提示 |
1.4 技术栈
| 技术领域 | 技术选型 | 版本要求 |
|---|---|---|
| 开发框架 | Flutter | >= 3.0.0 |
| 编程语言 | Dart | >= 2.17.0 |
| 设计规范 | Material Design 3 | - |
| 状态管理 | setState | - |
| 动画控制 | AnimationController | - |
| 目标平台 | 鸿蒙OS | API 21+ |
二、项目结构
lib/
├── main_anxiety_crusher.dart # 应用主入口(712行)
│ ├── AnxietyCrusherApp # 根应用组件
│ ├── AnxietyRecord # 数据模型
│ ├── AnxietyCrusherHomePage # 主页面
│ ├── Particle # 粒子模型
│ └── ParticlePainter # 粒子绘制器
三、数据模型
3.1 AnxietyRecord 模型
class AnxietyRecord {
final String id; // 唯一标识(时间戳)
final String content; // 烦恼内容
final DateTime createdAt; // 创建时间
DateTime? crushedAt; // 粉碎时间
bool isCrushed; // 是否已粉碎
AnxietyRecord({
required this.id,
required this.content,
required this.createdAt,
this.crushedAt,
this.isCrushed = false,
});
}
3.2 Particle 模型
class Particle {
double x; // X坐标
double y; // Y坐标
double vx; // X轴速度
double vy; // Y轴速度
double size; // 粒子大小
Color color; // 粒子颜色
double rotation; // 旋转角度
double rotationSpeed; // 旋转速度
double opacity = 1.0; // 透明度
void update() {
x += vx;
y += vy;
vy += 0.3; // 重力加速度
rotation += rotationSpeed;
opacity -= 0.015; // 渐隐效果
}
}
四、核心功能实现
4.1 粉碎动画实现
粉碎动画由三个阶段组成:震动、粒子生成、飞散动画。
void _startCrushAnimation() async {
setState(() => _isCrushing = true);
// 阶段1:震动效果
for (int i = 0; i < 5; i++) {
await _shakeController.forward(from: 0);
await Future.delayed(const Duration(milliseconds: 50));
}
// 阶段2:生成粒子
_generateParticles();
// 阶段3:粒子飞散动画
await _particleController.forward(from: 0);
// 更新记录状态
setState(() {
_currentRecord!.isCrushed = true;
_currentRecord!.crushedAt = DateTime.now();
_isCrushing = false;
_particles.clear();
});
}
4.2 粒子生成算法
生成50个随机属性的粒子,确保视觉效果丰富:
void _generateParticles() {
_particles.clear();
final random = Random();
for (int i = 0; i < 50; i++) {
_particles.add(Particle(
x: 0,
y: 0,
vx: (random.nextDouble() - 0.5) * 15, // 随机水平速度
vy: (random.nextDouble() - 0.5) * 15 - 5, // 随机垂直速度(向上偏移)
size: random.nextDouble() * 8 + 4, // 随机大小 4-12
color: [ // 随机颜色
const Color(0xFF6C5CE7),
const Color(0xFF00B894),
const Color(0xFFFDCB6E),
const Color(0xFFE17055),
const Color(0xFF74B9FF),
][random.nextInt(5)],
rotation: random.nextDouble() * 2 * pi,
rotationSpeed: (random.nextDouble() - 0.5) * 0.3,
));
}
}
4.3 粒子绘制器
使用 CustomPainter 实现高性能粒子渲染:
class ParticlePainter extends CustomPainter {
final List<Particle> particles;
final double progress;
void paint(Canvas canvas, Size size) {
final centerX = size.width / 2;
final centerY = size.height / 2;
for (var particle in particles) {
if (particle.opacity <= 0) continue;
final paint = Paint()
..color = particle.color.withValues(alpha: particle.opacity)
..style = PaintingStyle.fill;
canvas.save();
canvas.translate(centerX + particle.x, centerY + particle.y);
canvas.rotate(particle.rotation);
// 绘制不规则碎片形状
final path = Path();
path.moveTo(-particle.size / 2, -particle.size / 2);
path.lineTo(particle.size / 2, -particle.size / 3);
path.lineTo(particle.size / 3, particle.size / 2);
path.lineTo(-particle.size / 3, particle.size / 3);
path.close();
canvas.drawPath(path, paint);
canvas.restore();
}
}
bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}
五、UI设计
5.1 色彩系统
| 用途 | 色值 | 说明 |
|---|---|---|
| 主色调 | #6C5CE7 | 紫色,代表平静与治愈 |
| 辅助色1 | #00B894 | 绿色,代表已粉碎状态 |
| 辅助色2 | #FDCB6E | 黄色,代表待处理状态 |
| 辅助色3 | #E17055 | 橙色,用于粒子效果 |
| 辅助色4 | #74B9FF | 蓝色,用于粒子效果 |
| 背景渐变起始 | #6C5CE7 | 头部渐变 |
| 背景渐变结束 | #8B7FD4 | 头部渐变 |
5.2 页面结构
┌─────────────────────────────────┐
│ 🔮 焦虑粉碎机 │ ← 渐变头部
│ 写下烦恼,一键粉碎 │
│ ┌─────────┐ ┌─────────┐ │
│ │待粉碎 3 │ │已粉碎 5 │ │ ← 统计卡片
│ └─────────┘ └─────────┘ │
├─────────────────────────────────┤
│ 写下你的烦恼 │
│ ┌─────────────────────────┐ │
│ │ 工作压力太大了... │ │ ← 输入框
│ │ │ │
│ └─────────────────────────┘ │
│ ┌─────────────────────────┐ │
│ │ ⚡ 立即粉碎 │ │ ← 粉碎按钮
│ └─────────────────────────┘ │
├─────────────────────────────────┤
│ ▼ 待粉碎的烦恼 │
│ ┌─────────────────────────┐ │
│ │ ⏳ 待粉碎 今天 14:30 ⚡🗑️│ │ ← 烦恼卡片
│ │ 工作压力太大了... │ │
│ └─────────────────────────┘ │
├─────────────────────────────────┤
│ ▼ 已粉碎的烦恼 │
│ ┌─────────────────────────┐ │
│ │ ✓ 已粉碎 今天 14:25 🗑️│ │ ← 已粉碎(删除线)
│ │ ~~考试好紧张~~ │ │
│ └─────────────────────────┘ │
└─────────────────────────────────┘
5.3 交互设计
| 交互元素 | 触发方式 | 响应行为 |
|---|---|---|
| 输入框 | 点击 | 获取焦点,可输入文字 |
| 立即粉碎按钮 | 点击 | 触发粉碎动画,清空输入框 |
| 烦恼卡片-粉碎按钮 | 点击 | 对该记录触发粉碎动画 |
| 烦恼卡片-删除按钮 | 点击 | 删除该记录 |
| 空状态 | 无记录时显示 | 提示用户写下烦恼 |
六、动画详解
6.1 震动动画
使用正弦函数实现左右震动效果:
AnimatedBuilder(
animation: _shakeController,
builder: (context, child) {
final shake = sin(_shakeController.value * pi * 10) * 5;
return Transform.translate(
offset: Offset(shake, 0),
child: Container(...),
);
},
)
参数说明:
pi * 10:震动频率,数值越大震动越快* 5:震动幅度,单位是像素- 循环5次,每次100ms
6.2 粒子动画
粒子动画基于物理模拟:
| 物理属性 | 计算方式 | 效果 |
|---|---|---|
| 位置更新 | x += vx, y += vy |
匀速运动 |
| 重力模拟 | vy += 0.3 |
向下加速 |
| 旋转 | rotation += rotationSpeed |
自转效果 |
| 渐隐 | opacity -= 0.015 |
逐渐消失 |
6.3 动画时序
七、状态管理
7.1 状态分类
| 状态类型 | 状态名称 | 说明 |
|---|---|---|
| 输入状态 | _textController |
输入框文本 |
| 动画状态 | _isCrushing |
是否正在粉碎 |
| 粒子状态 | _particles |
当前粒子列表 |
| 记录状态 | _records |
所有烦恼记录 |
| 当前记录 | _currentRecord |
正在粉碎的记录 |
7.2 状态流转
八、性能优化
8.1 渲染优化
| 优化点 | 实现方式 | 效果 |
|---|---|---|
| 粒子复用 | 使用对象池(可扩展) | 减少内存分配 |
| 脏区域渲染 | CustomPainter精准重绘 | 只重绘动画区域 |
| 列表懒加载 | SliverList | 只渲染可见项 |
8.2 内存管理
void dispose() {
_textController.dispose();
_shakeController.dispose();
_particleController.dispose();
_scaleController.dispose();
super.dispose();
}
8.3 性能指标
| 指标 | 目标值 | 实测值 |
|---|---|---|
| 动画帧率 | 60fps | 60fps |
| 内存占用 | < 50MB | 待测试 |
| 启动时间 | < 2s | 待测试 |
九、常见问题
9.1 问题排查
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 粒子不显示 | AnimationController未启动 | 检查forward()调用 |
| 震动效果不明显 | 震动幅度太小 | 调整震动参数 |
| 记录状态不更新 | 未调用setState | 确保状态更新后调用setState |
| 历史记录丢失 | 内存存储重启清空 | 迁移至持久化存储 |
9.2 调试技巧
// 打印粒子数量
debugPrint('Particles: ${_particles.length}');
// 检查动画状态
debugPrint('IsCrushing: $_isCrushing');
debugPrint('Animation Value: ${_particleController.value}');
// 检查记录状态
for (var record in _records) {
debugPrint('Record: ${record.content}, Crushed: ${record.isCrushed}');
}
十、运行说明
10.1 环境要求
| 环境 | 版本要求 |
|---|---|
| Flutter SDK | >= 3.0.0 |
| Dart SDK | >= 2.17.0 |
| 鸿蒙OS | API 21+ |
10.2 运行命令
# 查看可用设备
flutter devices
# 运行到鸿蒙设备
flutter run -d 127.0.0.1:5555 lib/main_anxiety_crusher.dart
# 运行到Windows
flutter run -d windows -t lib/main_anxiety_crusher.dart
# 代码分析
flutter analyze lib/main_anxiety_crusher.dart
十一、扩展建议
11.1 功能扩展
| 功能 | 优先级 | 实现思路 |
|---|---|---|
| 数据持久化 | 高 | 使用SharedPreferences或SQLite |
| 粉碎音效 | 中 | 集成audioplayers播放音效 |
| 震动反馈 | 中 | 使用HapticFeedback |
| 分享功能 | 低 | 使用share_plus |
| 数据统计 | 低 | 记录粉碎次数、时间分布 |
11.2 设计扩展
| 方向 | 描述 |
|---|---|
| 主题切换 | 支持多种粉碎主题(火焰、雪花、星星等) |
| 粒子定制 | 允许用户选择粒子颜色和形状 |
| 成就系统 | 粉碎一定数量解锁成就徽章 |
十二、总结
焦虑粉碎机应用通过直观的"写下-粉碎"交互模式,帮助用户释放心理压力。应用核心亮点包括:
- 沉浸式动画:50个粒子飞散效果,视觉冲击力强
- 流畅交互:震动+粒子双重反馈,操作感好
- 状态管理:清晰的待粉碎/已粉碎分类
- 简洁设计:Material Design 3,界面清爽
应用代码结构清晰,共712行,无第三方依赖,易于理解和维护。后续可扩展数据持久化、音效反馈等功能,提升用户体验。
粉碎焦虑,释放压力!
更多推荐

所有评论(0)