Flutter 框架跨平台鸿蒙开发 - 平行时间线应用
摘要: 平行时间线是一款基于Flutter开发的哲学思考应用,通过可视化时间线探索人生不同选择的可能性。核心功能包括时间线展示、平行世界对比和指标分析,将人生选择分为职业、情感、居住、学业和生活五大类,并以紫粉色为主色调展现多元宇宙概念。应用采用Material Design 3规范,包含动画时间线、雷达图对比等交互设计,帮助用户直观理解"如果当初"的人生轨迹差异。技术栈使用F
欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net
一、项目概述
运行效果图




1.1 应用简介
平行时间线是一款独特的哲学思考应用,让用户能够探索不同选择下的人生可能性。应用以紫粉色为主色调,象征多元宇宙与无限可能。界面设计采用时间线分支的形式,将抽象的"如果当初"转化为可视化的平行世界。
应用通过记录人生中的关键选择节点,展示每个选择带来的影响,并生成对应的平行时间线。用户可以点击任意选择节点,查看如果当初做了不同选择,人生可能会走向怎样的方向。每个平行世界都有独特的人生指标,包括幸福感、事业成就、健康状况和人际关系。
1.2 核心功能
| 功能模块 | 功能描述 | 实现方式 |
|---|---|---|
| 时间线展示 | 展示人生关键选择节点 | 动画时间线 |
| 选择详情 | 查看选择的详细影响 | 对话框展示 |
| 平行世界 | 探索不同选择的结果 | 分支时间线 |
| 世界对比 | 对比不同人生轨迹 | 雷达图对比 |
| 指标分析 | 人生指标可视化 | 进度条展示 |
| 世界创建 | 创建新的平行世界 | 表单输入 |
1.3 选择类型体系
应用将人生选择划分为五大类型:
| 类型 | 图标 | 颜色 | 典型选择 |
|---|---|---|---|
| 职业选择 | work | #6B5B95 | 第一份工作、跳槽决策 |
| 情感选择 | favorite | #E91E63 | 表白、结婚、分手 |
| 居住选择 | home | #00BCD4 | 城市迁移、买房 |
| 学业选择 | school | #4CAF50 | 高考志愿、考研 |
| 生活选择 | wb_sunny | #FF9800 | 生活方式、节奏调整 |
1.4 人生指标体系
| 指标 | 说明 | 颜色 |
|---|---|---|
| 幸福感 | 整体幸福程度 | 粉色 |
| 事业成就 | 职业发展水平 | 蓝色 |
| 健康状况 | 身心健康状态 | 绿色 |
| 人际关系 | 社交与亲密关系 | 橙色 |
1.5 技术栈
| 技术领域 | 技术选型 | 版本要求 |
|---|---|---|
| 开发框架 | Flutter | >= 3.0.0 |
| 编程语言 | Dart | >= 2.17.0 |
| 设计规范 | Material Design 3 | - |
| 状态管理 | setState | - |
| 动画系统 | AnimationController | - |
| 目标平台 | 鸿蒙OS / Web | API 21+ |
1.6 项目结构
lib/
└── main_parallel_timeline.dart
├── ParallelTimelineApp # 应用入口
├── ChoiceType # 选择类型枚举
├── TimelineBranch # 时间线分支枚举
├── TimelineEvent # 时间线事件模型
├── ParallelWorld # 平行世界模型
├── ParallelTimelineHomePage # 主页面(底部导航)
├── _buildTimelinePage # 时间线页面
├── _buildWorldsPage # 平行世界页面
├── _buildComparisonPage # 对比页面
└── ComparisonRadarPainter # 雷达图绘制器
二、设计理念
2.1 平行时间线可视化
2.2 选择分支模型
2.3 色彩体系
应用采用紫粉色为主色调:
| 颜色类型 | 色值 | RGB | 用途 |
|---|---|---|---|
| 主色 | #6B5B95 | 107,91,149 | 导航、按钮、强调 |
| 辅助色 | #E91E63 | 233,30,99 | 平行世界标识 |
| 职业色 | #6B5B95 | 107,91,149 | 职业选择 |
| 情感色 | #E91E63 | 233,30,99 | 情感选择 |
| 居住色 | #00BCD4 | 0,188,212 | 居住选择 |
| 学业色 | #4CAF50 | 76,175,80 | 学业选择 |
| 生活色 | #FF9800 | 255,152,0 | 生活选择 |
2.4 选择探索流程
三、系统架构
3.1 整体架构图
3.2 类图设计
3.3 选择探索流程
四、核心功能实现
4.1 选择类型枚举
定义五大选择类型:
enum ChoiceType {
career('职业选择', Icons.work, Color(0xFF6B5B95)),
relationship('情感选择', Icons.favorite, Color(0xFFE91E63)),
location('居住选择', Icons.home, Color(0xFF00BCD4)),
education('学业选择', Icons.school, Color(0xFF4CAF50)),
lifestyle('生活选择', Icons.wb_sunny, Color(0xFFFF9800));
final String label;
final IconData icon;
final Color color;
const ChoiceType(this.label, this.icon, this.color);
}
4.2 时间线事件模型
定义时间线事件的数据结构:
class TimelineEvent {
final String id;
final String title;
final String description;
final DateTime date;
final ChoiceType type;
final String? choiceA;
final String? choiceB;
final String? selectedChoice;
final List<String> consequences;
TimelineEvent({
required this.id,
required this.title,
required this.description,
required this.date,
required this.type,
this.choiceA,
this.choiceB,
this.selectedChoice,
this.consequences = const [],
});
}
4.3 平行世界模型
定义平行世界的数据结构:
class ParallelWorld {
final String id;
final String name;
final String description;
final TimelineBranch branch;
final List<TimelineEvent> events;
final double divergencePoint;
final String divergenceChoice;
final int happiness;
final int success;
final int health;
final int relationship;
ParallelWorld({
required this.id,
required this.name,
required this.description,
required this.branch,
required this.events,
required this.divergencePoint,
required this.divergenceChoice,
required this.happiness,
required this.success,
required this.health,
required this.relationship,
});
}
4.4 时间线动画
时间线卡片的入场动画:
Widget _buildTimelineEventCard(TimelineEvent event, int index, bool isLast) {
return AnimatedBuilder(
animation: _timelineAnimationController,
builder: (context, child) {
final slideAnimation = Tween<Offset>(
begin: const Offset(-1, 0),
end: Offset.zero,
).animate(CurvedAnimation(
parent: _timelineAnimationController,
curve: Interval(
index * 0.15,
(index + 1) * 0.15,
curve: Curves.easeOut,
),
));
return SlideTransition(
position: slideAnimation,
child: child,
);
},
child: GestureDetector(
onTap: () => _showChoiceDialog(event),
child: Row(
children: [
// 时间线节点
Column(
children: [
Container(
width: 50,
height: 50,
decoration: BoxDecoration(
shape: BoxShape.circle,
gradient: RadialGradient(
colors: [event.type.color, event.type.color.withOpacity(0.7)],
),
),
child: Icon(event.type.icon, color: Colors.white),
),
// 连接线
if (!isLast)
Container(
width: 3,
height: 100,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [event.type.color, event.type.color.withOpacity(0.3)],
),
),
),
],
),
// 事件卡片
Expanded(child: Card(...)),
],
),
),
);
}
4.5 选择对话框
显示选择详情的对话框:
void _showChoiceDialog(TimelineEvent event) {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Row(
children: [
Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: event.type.color.withOpacity(0.2),
borderRadius: BorderRadius.circular(8),
),
child: Icon(event.type.icon, color: event.type.color),
),
const SizedBox(width: 12),
Expanded(child: Text(event.title)),
],
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(event.description),
const SizedBox(height: 20),
_buildChoiceOption(event, 'A', event.choiceA ?? '', true),
_buildChoiceOption(event, 'B', event.choiceB ?? '', false),
const SizedBox(height: 20),
...event.consequences.map((c) => Text(c)),
],
),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('关闭'),
),
ElevatedButton(
onPressed: () {
Navigator.pop(context);
_showParallelWorldDialog(event);
},
child: const Text('查看另一条时间线'),
),
],
),
);
}
4.6 雷达图对比
对比不同人生的雷达图绘制:
class ComparisonRadarPainter extends CustomPainter {
final List<int> originalScores;
final List<int> parallelScores;
final List<String> labels;
void paint(Canvas canvas, Size size) {
final center = Offset(size.width / 2, size.height / 2);
final radius = size.width / 2 - 50;
final sides = labels.length;
// 绘制网格
for (int level = 1; level <= 5; level++) {
final levelRadius = radius * level / 5;
final path = Path();
for (int i = 0; i < sides; i++) {
final angle = (2 * pi * i / sides) - pi / 2;
final x = center.dx + levelRadius * cos(angle);
final y = center.dy + levelRadius * sin(angle);
if (i == 0) path.moveTo(x, y);
else path.lineTo(x, y);
}
path.close();
canvas.drawPath(path, gridPaint);
}
// 绘制数据区域
_drawDataPolygon(canvas, center, radius, originalScores, sides,
TimelineBranch.original.color);
_drawDataPolygon(canvas, center, radius, parallelScores, sides,
TimelineBranch.parallel.color);
}
}
五、UI设计规范
5.1 配色方案
应用采用紫粉色为主色调:
| 颜色类型 | 色值 | 用途 |
|---|---|---|
| 主色 | #6B5B95 | 导航、按钮、强调 |
| 辅助色 | #E91E63 | 平行世界标识 |
| 职业色 | #6B5B95 | 职业选择节点 |
| 情感色 | #E91E63 | 情感选择节点 |
| 居住色 | #00BCD4 | 居住选择节点 |
| 学业色 | #4CAF50 | 学业选择节点 |
| 生活色 | #FF9800 | 生活选择节点 |
5.2 字体规范
| 元素 | 字号 | 字重 | 颜色 |
|---|---|---|---|
| 页面标题 | 20px | Bold | #000000 |
| 事件标题 | 18px | Bold | #000000 |
| 世界名称 | 20px | Bold | #000000 |
| 选择描述 | 14px | Regular | #666666 |
| 指标数值 | 14px | Bold | 指标颜色 |
5.3 组件规范
5.3.1 时间线节点
┌─────┐
│ 🎓 │ ← 选择类型图标
└─────┘
│ ← 连接线
│
┌─────────────────────────────────┐
│ [学业选择] ⟐ 分支 │
│ 高考志愿 │
│ 选择大学和专业 │
│ 2014年6月 │
│ ┌─────────────────────────────┐ │
│ │ ✓ 选择本地大学 │ │
│ └─────────────────────────────┘ │
└─────────────────────────────────┘
5.3.2 平行世界卡片
┌─────────────────────────────────────────┐
│ 🌍 创业者 │
│ 如果当初选择了创业公司... │
│ │
│ ⟐ 分歧选择:加入创业公司 │
│ │
│ 幸福 事业 健康 人际 │
│ ○65 ○80 ○55 ○60 │
└─────────────────────────────────────────┘
5.3.3 对比雷达图
幸福感
╱╲
╱ ╲
人际关系 ╱────╲ 事业成就
╲ ╱
╲╱
健康状况
── 现实时间线
── 平行时间线
六、交互设计
6.1 时间线交互
6.2 平行世界探索流程
6.3 页面切换状态
七、数据分析
7.1 统计指标
| 统计项 | 计算方式 | 说明 |
|---|---|---|
| 平行世界数 | _parallelWorlds.length | 探索的世界数量 |
| 选择节点数 | _originalEvents.length | 人生关键选择 |
| 平均幸福感 | 各世界幸福感平均值 | 整体幸福水平 |
| 分歧点分布 | 按类型统计分歧点 | 选择类型分布 |
7.2 指标对比分析
void _analyzeComparison() {
final originalHappiness = 70;
final parallelAvg = _parallelWorlds
.map((w) => w.happiness)
.reduce((a, b) => a + b) / _parallelWorlds.length;
if (parallelAvg > originalHappiness) {
// 平行世界平均幸福感更高
}
}
7.3 选择影响分析
| 选择类型 | 影响维度 | 典型影响 |
|---|---|---|
| 职业选择 | 事业成就、幸福感 | 收入、成就感、压力 |
| 情感选择 | 人际关系、幸福感 | 亲密关系、情感支持 |
| 居住选择 | 健康状况、人际关系 | 生活环境、社交圈 |
| 学业选择 | 事业成就、人际关系 | 职业方向、人脉 |
| 生活选择 | 幸福感、健康状况 | 生活品质、身心状态 |
7.4 时间分布分析
| 时间段 | 分析维度 | 应用价值 |
|---|---|---|
| 按年 | 年度选择统计 | 了解人生阶段 |
| 按类型 | 类型分布统计 | 了解选择倾向 |
| 按影响 | 影响程度分析 | 了解选择权重 |
| 按结果 | 结果对比分析 | 了解选择效果 |
八、扩展功能规划
8.1 后续版本规划
8.2 功能扩展建议
8.2.1 AI预测
AI辅助平行世界生成:
- 基于历史数据预测
- 个性化世界生成
- 可能性概率计算
- 智能建议推荐
8.2.2 人生模拟
人生模拟功能:
- 选择路径模拟
- 时间线推演
- 结果预测
- 风险评估
8.2.3 社区分享
社区互动功能:
- 匿名分享选择
- 经验交流
- 人生故事
- 互助建议
九、注意事项
9.1 开发注意事项
-
动画控制:AnimationController需要在dispose时释放
-
状态管理:使用setState管理本地状态,注意刷新时机
-
性能优化:列表使用SliverList实现懒加载
-
用户体验:选择详情要有足够的上下文信息
9.2 常见问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 时间线不显示 | 事件列表为空 | 检查_originalEvents |
| 动画不播放 | 控制器未启动 | 检查forward调用 |
| 平行世界为空 | 世界列表为空 | 检查_parallelWorlds |
| 雷达图不显示 | 数据为空 | 检查scores数组 |
9.3 使用提示
🌌 平行时间线使用小贴士 🌌
每一个选择都是一条平行时间线的起点。
探索不同选择,不是为了后悔,而是为了理解。
平行世界只是假设,现实才是你的人生。
珍惜当下,创造属于自己的精彩。
提示:定期回顾人生选择,有助于更好地规划未来。
十、运行说明
10.1 环境要求
| 环境 | 版本要求 |
|---|---|
| Flutter SDK | >= 3.0.0 |
| Dart SDK | >= 2.17.0 |
| 鸿蒙OS | API 21+ |
10.2 运行命令
# 查看可用设备
flutter devices
# 运行到Web服务器
flutter run -d web-server -t lib/main_parallel_timeline.dart --web-port 8131
# 运行到鸿蒙设备
flutter run -d 127.0.0.1:5555 lib/main_parallel_timeline.dart
# 运行到Windows
flutter run -d windows -t lib/main_parallel_timeline.dart
# 代码分析
flutter analyze lib/main_parallel_timeline.dart
十一、总结
平行时间线是一款独特的哲学思考应用,让用户能够探索不同选择下的人生可能性。应用以紫粉色为主色调,采用时间线分支的形式,将抽象的"如果当初"转化为可视化的平行世界。
从技术实现来看,应用使用动画时间线展示人生选择节点,通过对话框展示选择详情,使用底部面板展示平行世界,通过CustomPaint绘制雷达图对比不同人生。五大选择类型(职业、情感、居住、学业、生活)全面覆盖人生关键决策,四项人生指标(幸福感、事业成就、健康状况、人际关系)量化人生质量。
从用户体验来看,应用提供直观的时间线展示,让用户能够回顾人生关键选择。点击任意节点即可查看选择详情,探索平行世界让用户看到不同选择的可能性。对比功能让用户直观感受不同人生的差异。
应用不仅是一个选择记录工具,更是一个人生思考平台。它提醒我们:每一个选择都是一条平行时间线的起点;探索不同选择,不是为了后悔,而是为了理解;平行世界只是假设,现实才是你的人生;珍惜当下,创造属于自己的精彩。在人生的十字路口,平行时间线为我们提供了一种思考和感悟的方式。
探索无限可能的人生
更多推荐


所有评论(0)