Flutter for OpenHarmony星座运势 × 心理测试:用 Flutter 打造一款沉浸式心灵探索应用
Flutter for OpenHarmony星座运势 × 心理测试:用 Flutter 打造一款沉浸式心灵探索应用
Flutter for OpenHarmony星座运势 × 心理测试:用 Flutter 打造一款沉浸式心灵探索应用
在数字时代,人们越来越关注自我认知与情绪价值。无论是查看“今日运势”寻求心理慰藉,还是通过“性格测试”了解内在倾向,这类轻量级互动内容总能引发广泛共鸣。本文将带你深入剖析一款使用
Flutter 开发的趣味应用——《今日运势与心理测试》,从 UI 设计、状态管理到交互逻辑,全面解析如何用简洁代码构建一个兼具娱乐性与沉浸感的心灵小站。
完整效果展示

一、应用概览:双模块驱动的心灵体验
该应用包含两大核心功能模块:
- 星座运势:用户点击任意星座(如白羊座、天蝎座),即可生成一条带有评分(0–100)和个性化文案的今日运势;
- 心理小测试:通过三个简短问题,模拟分析用户性格类型,并在 2 秒后返回一段富有洞察力的性格画像。
整个应用采用 深色主题(Dark Mode),背景为 #121212,主色调为深紫色(deepPurple),营造出神秘、宁静又略带科技感的氛围,完美契合“命运”与“潜意识”的主题。
二、UI/UX 设计亮点:Material 3 + 沉浸式深色美学
1. 统一而克制的视觉语言
theme: ThemeData(
primaryColor: Colors.deepPurple,
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple, brightness: Brightness.dark),
useMaterial3: true,
scaffoldBackgroundColor: const Color(0xFF121212),
)

- 启用 Material You(Material 3),自动适配系统深色模式;
- 全局背景设为接近纯黑的
#121212,减少视觉疲劳;- 卡片使用
grey[800]/grey[900]等深灰层级,形成柔和对比,避免刺眼。
2. 星座按钮:Wrap 布局 + 圆角标签
12 个星座以 Wrap 组件排列,自动换行,适配不同屏幕宽度:
Wrap(
spacing: 8,
runSpacing: 8,
children: _zodiacs.map((zodiac) => ElevatedButton(...)).toList(),
)

每个按钮采用半透明深紫底色(opacity: 0.3)+ 白色文字 + 圆角设计,点击反馈清晰,整体如“星盘”般有序排列。
3. 运势卡片:动态评分 + 情绪化色彩
运势结果以卡片形式展示,核心亮点在于 线性进度条:
LinearProgressIndicator(
value: data['score'] / 100,
color: data['score'] > 60 ? Colors.green : Colors.red,
)

- 评分 >60 显示绿色(积极),≤60 显示红色(谨慎),用颜色传递情绪;
- 配合图标(如狮子座用
Icons.star,水瓶座用Icons.bolt),强化星座符号联想。
4. 心理测试:卡片式问答 + 悬念式加载
- 每道题封装在深灰色
Card中,问题加粗,选项灰色弱化,层次分明;- 点击“开始测试”后,先显示“正在分析你的性格…”,制造期待感;
- 2 秒后揭晓结果,模拟“AI 分析”过程,提升趣味性。
三、核心逻辑解析:随机性与模拟智能
1. 星座运势生成:伪随机但有温度
虽然运势内容由随机数决定,但文案库经过精心设计:
final List<String> texts = [
'今天是行动的一天!大胆尝试新事物...',
'保持耐心。今天适合处理细节工作...',
'社交运极佳。你会遇到有趣的人...',
// ...
];

每条文案都包含 具体建议 + 情绪引导,让用户感觉“被理解”,而非冷冰冰的随机语句。
2. 心理测试:基于选择的模拟分析
当前版本虽未真正记录用户选项(仅为演示),但其架构已预留扩展空间:
_quizQuestions结构清晰,易于接入真实答题逻辑;_getPersonalityResult返回四种典型人格画像,语言风格兼具专业性与亲和力,如:“你是一个极度理性的人……但也需要学会偶尔放松,感受生活的情感面。”
这种“肯定+建议”的句式,极易引发用户共鸣与分享欲。
四、工程实践:可维护性与扩展性
1. 数据与 UI 分离
- 星座列表
_zodiacs、测试题目_quizQuestions、运势文案texts均独立定义; - 图标映射
_getZodiacIcon封装在函数中,便于未来替换为自定义 SVG 或图片。
2. 组件化思维
- 运势卡片抽离为
_buildFortuneCard方法,避免build函数臃肿; - 所有状态(
_currentFortune,_quizResult,_isTestCompleted)集中管理,逻辑清晰。
3. 异步模拟真实场景
Future.delayed(const Duration(seconds: 2), () {
// 更新结果
});
通过延迟更新,模拟网络请求或 AI 计算过程,提升用户体验的真实感。
五、未来优化方向
| 方向 | 建议 |
|---|---|
| 真实答题逻辑 | 记录用户选项,根据 A/B 选择计算性格维度(如内向/外向) |
| 每日缓存机制 | 使用 shared_preferences 缓存当日运势,避免重复生成 |
| 分享功能 | 添加“分享我的运势”按钮,生成图片或文本供社交传播 |
| 动画增强 | 为运势卡片添加淡入动画,为进度条添加数值滚动效果 |
结语
这款《今日运势与心理测试》应用,虽仅数百行代码,却完整展现了 Flutter 在构建情感化、互动型应用上的独特优势。它没有复杂的业务逻辑,却通过精巧的 UI 设计、有温度的文案和恰到好处的交互反馈,成功营造出一种“数字占卜”的仪式感。
🌐 加入社区
欢迎加入 开源鸿蒙跨平台开发者社区,获取最新资源与技术支持:
👉 开源鸿蒙跨平台开发者社区
完整代码展示
import 'dart:math';
import 'package:flutter/material.dart';
void main() {
runApp(const FortuneApp());
}
class FortuneApp extends StatelessWidget {
const FortuneApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '今日运势',
theme: ThemeData(
primaryColor: Colors.deepPurple,
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.deepPurple, brightness: Brightness.dark),
useMaterial3: true,
scaffoldBackgroundColor: const Color(0xFF121212), // 深色背景
),
home: const FortuneHome(),
debugShowCheckedModeBanner: false,
);
}
}
class FortuneHome extends StatefulWidget {
const FortuneHome({super.key});
@override
State<FortuneHome> createState() => _FortuneHomeState();
}
class _FortuneHomeState extends State<FortuneHome> {
// 模拟的星座列表
final List<String> _zodiacs = [
'白羊座',
'金牛座',
'双子座',
'巨蟹座',
'狮子座',
'处女座',
'天秤座',
'天蝎座',
'射手座',
'摩羯座',
'水瓶座',
'双鱼座'
];
// 模拟的心理测试题目
final List<Map<String, dynamic>> _quizQuestions = [
{
'question': '在压力之下,你更倾向于:',
'choices': ['A. 寻找逻辑解决方案', 'B. 寻求朋友的情感支持']
},
{
'question': '周末你更愿意:',
'choices': ['A. 待在家里充电', 'B. 出去社交冒险']
},
{
'question': '面对未知,你的第一反应是:',
'choices': ['A. 兴奋和好奇', 'B. 谨慎和担忧']
},
];
// 测试结果
String _quizResult = '';
bool _isTestCompleted = false;
// 当前选中的星座运势
Map<String, dynamic>? _currentFortune;
// 随机数生成器
final Random _random = Random();
// 生成星座运势
void _generateFortune(String zodiac) {
setState(() {
_currentFortune = {
'name': zodiac,
'score': _random.nextInt(100),
'text': _getFortuneText(),
'icon': _getZodiacIcon(zodiac),
};
});
}
// 获取运势文案
String _getFortuneText() {
final List<String> texts = [
'今天是行动的一天!大胆尝试新事物,好运会眷顾勇敢者。',
'保持耐心。今天适合处理细节工作,不宜做重大决策。',
'社交运极佳。你会遇到有趣的人,或者收到意想不到的消息。',
'财运小爆发。可能会有额外的收入,但也别忘了储蓄。',
'注意休息。身体在向你发出信号,不要过度透支精力。',
'灵感迸发。你的创意想法今天会得到他人的高度认可。',
];
return texts[_random.nextInt(texts.length)];
}
// 获取星座图标 (使用Material Icon模拟)
IconData _getZodiacIcon(String zodiac) {
switch (zodiac) {
case '白羊座':
return Icons.whatshot;
case '金牛座':
return Icons.eco;
case '双子座':
return Icons.chat;
case '巨蟹座':
return Icons.heart_broken;
case '狮子座':
return Icons.star;
case '处女座':
return Icons.cleaning_services;
case '天秤座':
return Icons.scale;
case '天蝎座':
return Icons.visibility;
case '射手座':
return Icons.explore;
case '摩羯座':
return Icons.lunch_dining;
case '水瓶座':
return Icons.bolt;
case '双鱼座':
return Icons.opacity;
default:
return Icons.question_mark;
}
}
// 处理心理测试逻辑
void _startQuiz() {
setState(() {
_isTestCompleted = false;
_quizResult = '正在分析你的性格...';
// 模拟异步处理
Future.delayed(const Duration(seconds: 2), () {
final int random = _random.nextInt(4);
setState(() {
_quizResult = _getPersonalityResult(random);
_isTestCompleted = true;
});
});
});
}
String _getPersonalityResult(int index) {
switch (index) {
case 0:
return '【逻辑分析型】\n你是一个极度理性的人。在面对问题时,你习惯用逻辑和数据说话。你擅长规划,但也需要学会偶尔放松,感受生活的情感面。';
case 1:
return '【社交达人型】\n你充满活力,天生的社交家。你从与他人的互动中获取能量,善于沟通。注意在喧嚣中保持独立的思考。';
case 2:
return '【沉稳内敛型】\n你深思熟虑,是值得信赖的伙伴。你喜欢按部就班,厌恶风险。你的稳定是团队的基石,偶尔也可以尝试跳出舒适区。';
case 3:
return '【冒险探索型】\n你对世界充满好奇,渴望新鲜感。你适应力强,敢于挑战。记得在追求刺激的同时,做好风险评估。';
default:
return '【全能型】\n你拥有平衡的性格,能根据环境切换模式。这既是优点也是挑战,找到核心的自我会让你更强大。';
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('✨ 今日运势与测试'),
centerTitle: true,
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// --- 星座运势模块 ---
const Text(
'🌟 点击查看星座运势',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
const SizedBox(height: 10),
Wrap(
spacing: 8,
runSpacing: 8,
children: _zodiacs.map((zodiac) {
return ElevatedButton(
onPressed: () => _generateFortune(zodiac),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.deepPurple.withOpacity(0.3),
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
padding: const EdgeInsets.symmetric(
horizontal: 15, vertical: 10),
),
child: Text(zodiac),
);
}).toList(),
),
// 星座结果展示
if (_currentFortune != null) _buildFortuneCard(_currentFortune!),
const SizedBox(height: 30),
// --- 心理测试模块 ---
const Text(
'🧠 心理小测试',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
const SizedBox(height: 10),
const Text(
'回答以下3个问题,了解你的潜意识性格倾向:',
style: TextStyle(color: Colors.grey),
),
const SizedBox(height: 10),
..._quizQuestions.map((q) {
return Card(
color: Colors.grey[900],
child: Padding(
padding: const EdgeInsets.all(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(q['question']!,
style: const TextStyle(fontWeight: FontWeight.bold)),
const SizedBox(height: 5),
...List.generate(q['choices']!.length, (index) {
return Text(
'${['A', 'B'][index]}. ${q['choices']![index]}',
style: const TextStyle(color: Colors.grey),
);
}),
],
),
),
);
}).toList(),
const SizedBox(height: 10),
Center(
child: ElevatedButton(
onPressed: _startQuiz,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.orange,
foregroundColor: Colors.white,
),
child: const Text('开始测试'),
),
),
// 测试结果展示
if (_quizResult.isNotEmpty)
Card(
color: Colors.grey[800],
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'📊 测试结果',
style: TextStyle(
fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 10),
Text(
_quizResult,
style: const TextStyle(height: 1.6),
),
],
),
),
),
],
),
),
);
}
// 构建运势卡片组件
Widget _buildFortuneCard(Map<String, dynamic> data) {
return Card(
margin: const EdgeInsets.symmetric(vertical: 10),
color: Colors.purple.withOpacity(0.1),
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(data['icon'], color: Colors.purple, size: 30),
const SizedBox(width: 10),
Text(
'${data['name']} 今日运势',
style: const TextStyle(
fontSize: 18, fontWeight: FontWeight.bold),
),
],
),
const SizedBox(height: 10),
LinearProgressIndicator(
value: data['score'] / 100,
backgroundColor: Colors.grey[800],
color: data['score'] > 60 ? Colors.green : Colors.red,
),
const SizedBox(height: 5),
Text(
'评分: ${data['score']}/100',
style: TextStyle(
color: data['score'] > 60 ? Colors.green : Colors.red),
),
const SizedBox(height: 10),
Text(
data['text'],
style: const TextStyle(height: 1.5),
),
],
),
),
);
}
}
更多推荐



所有评论(0)