
前言
成就系统是游戏化设计的重要组成部分,能激励用户持续使用App。用户完成特定任务后解锁成就,获得成就感和满足感。我的成就页面就是展示这些成就的地方。本文将详细介绍如何在Flutter for OpenHarmony环境下实现一个完整的成就展示页面。通过合理的成就设计,可以有效提升用户的参与度和留存率,让垃圾分类学习变得更有趣味性。
技术要点概览
本页面涉及的核心技术点包括以下几个方面:
- GridView.builder:网格布局展示成就卡片
- LinearProgressIndicator:进度条显示成就完成度
- 条件渲染:已解锁和未解锁状态的不同样式
- 渐变背景:头部统计区域的视觉效果
成就数据结构
每个成就包含图标、名称、描述和解锁状态:
dart
class AchievementPage extends StatelessWidget {
const AchievementPage({super.key});
@override
Widget build(BuildContext context) {
// 成就数据列表
// 实际项目中这些数据应该从控制器获取,根据用户行为动态计算解锁状态
final achievements = [
{'icon': '🌱', 'name': '环保新手', 'desc': '完成首次搜索', 'unlocked': true, 'progress': 1.0},
{'icon': '📚', 'name': '学习达人', 'desc': '浏览10个分类', 'unlocked': true, 'progress': 1.0},
{'icon': '🎯', 'name': '答题高手', 'desc': '答题正确率80%', 'unlocked': false, 'progress': 0.6},
{'icon': '⭐', 'name': '收藏专家', 'desc': '收藏20个物品', 'unlocked': false, 'progress': 0.35},
{'icon': '🏆', 'name': '环保卫士', 'desc': '累计搜索100次', 'unlocked': false, 'progress': 0.45},
{'icon': '💎', 'name': '分类大师', 'desc': '获得1000积分', 'unlocked': false, 'progress': 0.2},
];
成就设计有几个层次:
- 入门级:环保新手、学习达人,容易达成,给用户信心
- 进阶级:答题高手、收藏专家,需要一定努力
- 高级:环保卫士、分类大师,需要长期使用才能达成
设计思路:用emoji作为成就图标,既生动又不需要额外的图片资源。每个emoji都和成就主题相关,比如🌱代表新手,🏆代表卫士。
页面头部统计
在成就列表上方显示统计信息:
dart
// 计算已解锁的成就数量
final unlockedCount = achievements.where((a) => a['unlocked'] == true).length;
return Scaffold(
appBar: AppBar(title: const Text('我的成就')),
body: Column(
children: [
// 头部统计区域
_buildHeader(unlockedCount, achievements.length),
// 成就网格
Expanded(
child: GridView.builder(
padding: EdgeInsets.all(16.w),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 12.w,
mainAxisSpacing: 12.h,
childAspectRatio: 0.85,
),
itemCount: achievements.length,
itemBuilder: (context, index) {
final item = achievements[index];
return _buildAchievementCard(item);
},
),
),
],
),
);
}
头部统计组件
dart
Widget _buildHeader(int unlocked, int total) {
return Container(
margin: EdgeInsets.all(16.w),
padding: EdgeInsets.all(20.w),
decoration: BoxDecoration(
gradient: const LinearGradient(
colors: [AppTheme.primaryColor, AppTheme.secondaryColor],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
borderRadius: BorderRadius.circular(16.r),
),
child: Row(
children: [
// 奖杯图标
Container(
width: 60.w,
height: 60.w,
decoration: BoxDecoration(
color: Colors.white24,
borderRadius: BorderRadius.circular(12.r),
),
child: Icon(Icons.emoji_events, color: Colors.white, size: 36.sp),
),
SizedBox(width: 16.w),
// 统计文字
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'已解锁 $unlocked / $total',
style: TextStyle(
color: Colors.white,
fontSize: 20.sp,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 4.h),
Text(
'继续努力,解锁更多成就!',
style: TextStyle(color: Colors.white70, fontSize: 14.sp),
),
],
),
),
],
),
);
}
成就卡片样式
已解锁和未解锁的成就有不同的样式:
dart
Widget _buildAchievementCard(Map<String, dynamic> item) {
final unlocked = item['unlocked'] as bool;
final progress = item['progress'] as double;
return Container(
decoration: BoxDecoration(
color: unlocked ? Colors.white : Colors.grey.shade100,
borderRadius: BorderRadius.circular(12.r),
border: Border.all(
color: unlocked ? AppTheme.primaryColor : Colors.grey.shade300,
width: unlocked ? 2 : 1,
),
boxShadow: unlocked ? [
BoxShadow(
color: AppTheme.primaryColor.withOpacity(0.2),
blurRadius: 8,
offset: const Offset(0, 2),
),
] : null,
),
- 已解锁:白色背景,主题色边框,带阴影,看起来明亮醒目
- 未解锁:灰色背景,灰色边框,无阴影,看起来暗淡
卡片内容
卡片内容包含图标、名称、描述,未解锁的还有进度条:
dart
child: Padding(
padding: EdgeInsets.all(12.w),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// 成就图标
Text(
item['icon'] as String,
style: TextStyle(
fontSize: 40.sp,
color: unlocked ? null : Colors.grey,
),
),
SizedBox(height: 8.h),
// 成就名称
Text(
item['name'] as String,
style: TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.bold,
color: unlocked ? Colors.black : Colors.grey,
),
),
SizedBox(height: 4.h),
// 成就描述
Text(
item['desc'] as String,
style: TextStyle(fontSize: 12.sp, color: Colors.grey),
textAlign: TextAlign.center,
),
SizedBox(height: 8.h),
// 已解锁显示对勾,未解锁显示进度条
if (unlocked)
Icon(Icons.check_circle, color: AppTheme.primaryColor, size: 24.sp)
else
_buildProgressBar(progress),
],
),
),
);
}
未解锁的成就,图标和文字都是灰色的,给人一种"还没点亮"的感觉。
进度条组件
dart
Widget _buildProgressBar(double progress) {
return Column(
children: [
// 进度条
ClipRRect(
borderRadius: BorderRadius.circular(4.r),
child: LinearProgressIndicator(
value: progress,
backgroundColor: Colors.grey.shade300,
valueColor: AlwaysStoppedAnimation(AppTheme.primaryColor.withOpacity(0.5)),
minHeight: 6.h,
),
),
SizedBox(height: 4.h),
// 进度百分比
Text(
'${(progress * 100).toInt()}%',
style: TextStyle(fontSize: 10.sp, color: Colors.grey),
),
],
);
}
条件渲染 :
if (unlocked) ... else ...是Dart的条件表达式,只有已解锁的成就才显示对勾图标,未解锁的显示进度条。
成就系统的实现思路
实际项目中,成就的解锁状态应该是动态计算的:
dart
class AchievementController extends GetxController {
final achievements = <Achievement>[].obs;
@override
void onInit() {
super.onInit();
_loadAchievements();
}
void _loadAchievements() {
achievements.value = [
Achievement(
id: 'beginner',
name: '环保新手',
desc: '完成首次搜索',
icon: '🌱',
condition: () => searchCount >= 1,
getProgress: () => min(searchCount / 1, 1.0),
),
Achievement(
id: 'learner',
name: '学习达人',
desc: '浏览10个分类',
icon: '📚',
condition: () => viewedCategories >= 10,
getProgress: () => min(viewedCategories / 10, 1.0),
),
// ... 更多成就
];
}
/// 检查并更新成就状态
void checkAchievements() {
for (var achievement in achievements) {
if (!achievement.unlocked && achievement.condition()) {
achievement.unlocked = true;
_showUnlockNotification(achievement);
}
}
}
/// 显示解锁通知
void _showUnlockNotification(Achievement achievement) {
Get.snackbar(
'🎉 成就解锁',
'恭喜获得「${achievement.name}」成就!',
backgroundColor: AppTheme.primaryColor,
colorText: Colors.white,
duration: const Duration(seconds: 3),
);
}
}
成就解锁的时机
成就解锁应该在用户完成相应行为时检查:
dart
// 在搜索时检查成就
void onSearch(String keyword) {
searchCount++;
achievementController.checkAchievements();
}
// 在答题完成时检查成就
void onQuizComplete(int score, int total) {
final accuracy = score / total;
if (accuracy >= 0.8) {
quizHighAccuracyCount++;
}
achievementController.checkAchievements();
}
游戏化设计的价值
成就系统的价值在于:
1. 引导用户行为:通过设置成就目标,引导用户探索App的各种功能。
2. 增加用户粘性:用户为了解锁成就会持续使用App。
3. 提供正向反馈:每次解锁成就都是对用户的肯定,让用户感到满足。
4. 社交分享:用户可以分享自己的成就,带来新用户。
成就系统是个很好的用户激励机制,做好了能显著提升用户活跃度和留存率。通过精心设计的成就体系,可以引导用户探索应用的各项功能,同时给予用户正向的反馈和激励。
总结
本文详细介绍了成就页面的实现方案,包括成就数据结构设计、卡片样式区分、进度展示等核心功能。通过游戏化的设计思路,可以让垃圾分类学习变得更加有趣,提升用户的参与积极性。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net