Flutter for OpenHarmony星座运势 × 心理测试:用 Flutter 打造一款沉浸式心灵探索应用

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


完整效果展示
在这里插入图片描述
在这里插入图片描述

一、应用概览:双模块驱动的心灵体验

该应用包含两大核心功能模块:

  1. 星座运势:用户点击任意星座(如白羊座、天蝎座),即可生成一条带有评分(0–100)和个性化文案的今日运势;
  2. 心理小测试:通过三个简短问题,模拟分析用户性格类型,并在 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),
            ),
          ],
        ),
      ),
    );
  }
}

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐