Flutter for OpenHarmony 社团管理App实战 - 我的积分实现
本文介绍了如何在Flutter中实现社团应用的积分模块,主要包括: 使用StatelessWidget构建无状态积分页面 通过Provider进行状态管理,实时显示用户积分 模拟积分历史数据,包含获取和消费记录 设计积分卡片展示区域,采用渐变背景和醒目字体 添加积分兑换和规则查看功能按钮 构建积分明细列表,展示积分变动记录 实现积分规则弹窗,使用AlertDialog组件 该实现采用了Materi

积分系统是社团管理应用中激励用户参与的重要机制,用户可以通过参加活动获取积分。这篇文章带大家实现我的积分模块。
页面结构搭建
积分页面用StatelessWidget来实现:
class PointsPage extends StatelessWidget {
const PointsPage({super.key});
页面不需要维护内部状态,所有数据都从Provider获取。
const构造函数可以让Flutter在重建时复用Widget实例。
导入依赖包
在文件开头导入需要的包:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
material.dart提供Material Design风格的组件。
provider用于状态管理。
还需要导入项目内的文件:
import '../../providers/app_provider.dart';
app_provider包含用户积分数据。
使用相对路径引入,…/…/表示向上两级目录。
模拟积分历史数据
在build方法中定义积分历史数据:
Widget build(BuildContext context) {
final pointsHistory = [
{
'title': '参加ACM培训',
'points': 20,
'time': '2024-01-10',
'type': 'earn'
},
{
'title': '完成任务',
'points': 10,
'time': '2024-01-08',
'type': 'earn'
},
积分历史用Map列表模拟,包含标题、积分数、时间和类型。
实际项目中这些数据应该从后端获取。
继续添加更多记录:
{
'title': '签到奖励',
'points': 5,
'time': '2024-01-07',
'type': 'earn'
},
{
'title': '兑换礼品',
'points': -50,
'time': '2024-01-05',
'type': 'spend'
},
{
'title': '参加摄影活动',
'points': 30,
'time': '2024-01-03',
'type': 'earn'
},
{
'title': '邀请新成员',
'points': 15,
'time': '2024-01-01',
'type': 'earn'
},
];
type字段区分获取(earn)和消费(spend)。
消费记录的points为负数。
构建页面骨架
使用Scaffold搭建基本结构:
return Scaffold(
appBar: AppBar(
title: const Text('我的积分')
),
Scaffold是Material Design的基础布局组件。
标题直接写"我的积分",简洁明了。
数据监听
使用Consumer监听AppProvider的数据变化:
body: Consumer<AppProvider>(
builder: (context, provider, _) {
return Column(
children: [
Consumer会在数据变化时自动重建子组件。
Column纵向排列积分卡片和明细列表。
积分展示卡片
页面顶部显示当前积分:
Container(
padding: const EdgeInsets.all(32),
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [Color(0xFF4A90E2), Color(0xFF357ABD)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
),
使用渐变背景让积分区域更加醒目。
32像素的padding让内容有足够的呼吸空间。
积分数值显示:
child: Column(
children: [
const Text(
'当前积分',
style: TextStyle(
color: Colors.white70,
fontSize: 16
)
),
const SizedBox(height: 8),
Text(
'${provider.currentUser.points}',
style: const TextStyle(
color: Colors.white,
fontSize: 48,
fontWeight: FontWeight.bold
)
),
const SizedBox(height: 16),
48像素的超大字号让积分数值成为视觉焦点。
白色粗体在蓝色背景上非常醒目。
操作按钮区域
添加积分兑换和规则查看按钮:
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
_buildActionButton(
Icons.card_giftcard,
'积分兑换',
() {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('兑换功能开发中')
)
);
}
),
const SizedBox(width: 32),
_buildActionButton(
Icons.rule,
'积分规则',
() {
_showPointsRules(context);
}
),
],
),
],
),
),
两个按钮横向排列,间距32像素。
积分兑换暂时显示开发中提示。
明细标题栏
积分明细区域的标题栏:
Padding(
padding: const EdgeInsets.all(16),
child: Row(
children: [
const Text(
'积分明细',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16
)
),
const Spacer(),
TextButton(
onPressed: () {},
child: const Text('全部记录')
),
],
),
),
左侧显示标题,右侧显示查看全部按钮。
Spacer让两者分别靠左和靠右对齐。
积分明细列表
使用ListView.builder构建明细列表:
Expanded(
child: ListView.builder(
padding: const EdgeInsets.symmetric(horizontal: 16),
itemCount: pointsHistory.length,
itemBuilder: (context, index) {
final item = pointsHistory[index];
final isEarn = item['type'] == 'earn';
Expanded让列表占据剩余空间。
isEarn变量判断是获取还是消费积分。
明细卡片设计
每条明细用Card和ListTile组合展示:
return Card(
margin: const EdgeInsets.only(bottom: 8),
child: ListTile(
leading: CircleAvatar(
backgroundColor: isEarn
? Colors.green.withOpacity(0.1)
: Colors.red.withOpacity(0.1),
child: Icon(
isEarn ? Icons.add : Icons.remove,
color: isEarn ? Colors.green : Colors.red,
),
),
获取积分用绿色加号图标,消费积分用红色减号图标。
颜色区分让用户一眼就能识别记录类型。
明细信息显示:
title: Text(item['title'] as String),
subtitle: Text(item['time'] as String),
trailing: Text(
'${isEarn ? '+' : ''}${item['points']}',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
color: isEarn ? Colors.green : Colors.red,
),
),
),
);
},
),
),
],
);
},
),
);
}
积分数值显示正负号,获取显示加号,消费显示负数。
颜色和图标保持一致。
操作按钮组件
定义构建操作按钮的方法:
Widget _buildActionButton(
IconData icon,
String label,
VoidCallback onTap
) {
return GestureDetector(
onTap: onTap,
child: Column(
children: [
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.2),
borderRadius: BorderRadius.circular(12),
),
child: Icon(icon, color: Colors.white, size: 24),
),
const SizedBox(height: 8),
Text(
label,
style: const TextStyle(
color: Colors.white,
fontSize: 12
)
),
],
),
);
}
按钮使用半透明白色背景,图标和文字都是白色。
GestureDetector处理点击事件。
积分规则弹窗
定义显示积分规则的方法:
void _showPointsRules(BuildContext context) {
showModalBottomSheet(
context: context,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(16)
)
),
builder: (ctx) => Padding(
padding: const EdgeInsets.all(20),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'积分规则',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold
)
),
const SizedBox(height: 16),
使用BottomSheet从底部弹出,顶部有圆角。
mainAxisSize设为min让弹窗高度自适应内容。
规则列表:
_buildRuleItem('参加活动', '+10~30积分'),
_buildRuleItem('完成任务', '+5~20积分'),
_buildRuleItem('每日签到', '+5积分'),
_buildRuleItem('邀请新成员', '+15积分'),
_buildRuleItem('发布优质内容', '+10积分'),
const SizedBox(height: 16),
const Text(
'积分可用于兑换社团周边、活动优先报名等权益',
style: TextStyle(
color: Colors.grey,
fontSize: 13
)
),
const SizedBox(height: 20),
],
),
),
);
}
列出常见的积分获取方式和对应的积分数。
底部说明积分的用途。
规则行组件
定义构建规则行的方法:
Widget _buildRuleItem(String action, String points) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(action),
Text(
points,
style: const TextStyle(
color: Color(0xFF4A90E2),
fontWeight: FontWeight.bold
)
),
],
),
);
}
}
行为描述靠左,积分数靠右。
积分数用蓝色粗体突出显示。
积分系统的激励作用
积分系统是提升用户活跃度的有效手段。
通过设置合理的积分获取规则,可以引导用户参与社团活动。
积分兑换功能给用户提供了使用积分的出口。
形成完整的激励闭环。
颜色区分的设计考虑
获取积分使用绿色,消费积分使用红色。
这是符合用户直觉的设计。
绿色通常代表正面、增加,红色代表负面、减少。
这种颜色编码让用户无需阅读文字就能快速理解。
小结
积分页面通过大字号展示当前积分余额,让用户一目了然。操作按钮提供积分兑换和规则查看的入口。积分明细列表显示获取和消费记录,使用颜色区分不同类型。积分规则弹窗说明各种获取积分的方式。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
更多推荐



所有评论(0)