
引言
邀请好友是用户增长的重要功能,通过奖励机制激励用户分享App。本篇将实现邀请好友页面,包含邀请码、分享方式和邀请记录。邀请功能不仅能够扩大用户基数,还能通过社交传播提升App的知名度。在现代移动应用中,邀请功能已成为用户获取的重要渠道,通过设计合理的奖励机制和便捷的分享方式,可以显著提升用户的邀请意愿。
功能设计
邀请好友页面包含以下核心功能:
- 邀请奖励说明卡片:展示邀请奖励规则,激励用户参与。通过清晰的奖励说明,让用户了解邀请的收益
- 邀请码展示(可复制):提供唯一的邀请码,方便用户分享。邀请码是邀请功能的核心,需要确保其唯一性和易记性
- 多种分享方式:支持微信、二维码、链接等多种分享渠道。不同的分享方式满足不同用户的需求
- 邀请记录列表:展示邀请的好友及其完成状态。记录展示帮助用户追踪邀请进度和奖励获取情况
数据模型定义
dart
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class InviteRecord {
final String userId;
final String userName;
final String status;
final String reward;
final DateTime inviteTime;
InviteRecord({
required this.userId,
required this.userName,
required this.status,
required this.reward,
required this.inviteTime,
});
}
InviteRecord数据模型用于表示单条邀请记录。userId是被邀请用户的唯一标识,用于后端数据关联。userName是被邀请用户的昵称,在UI中直接显示。status字段表示邀请的当前状态,包括"待完成首次组队"和"已完成首次组队"两种状态。reward字段存储该邀请对应的奖励信息,如"+50积分"或"待发放"。inviteTime记录邀请发生的时间,用于在UI中显示邀请的相对时间。这个模型设计简洁但包含了邀请功能所需的所有关键信息。
dart
class InviteController extends GetxController {
final inviteCode = 'INVITE2024ABC'.obs;
final inviteRecords = <InviteRecord>[].obs;
final totalReward = 0.obs;
@override
void onInit() {
super.onInit();
loadInviteRecords();
}
InviteController继承GetxController,使用GetX框架的响应式编程模式。inviteCode是一个响应式变量,存储当前用户的邀请码。在实际项目中,这个邀请码应该从后端API获取,确保每个用户都有唯一的邀请码。inviteRecords是一个响应式列表,存储所有的邀请记录。totalReward是一个响应式变量,存储用户已获得的总奖励。onInit方法在控制器初始化时自动调用,用于加载邀请记录数据。
dart
void loadInviteRecords() {
inviteRecords.value = [
InviteRecord(
userId: '1',
userName: '玩家A',
status: '已完成首次组队',
reward: '+50积分',
inviteTime: DateTime.now().subtract(const Duration(days: 5)),
),
InviteRecord(
userId: '2',
userName: '玩家B',
status: '待完成首次组队',
reward: '待发放',
inviteTime: DateTime.now().subtract(const Duration(days: 2)),
),
InviteRecord(
userId: '3',
userName: '玩家C',
status: '已完成首次组队',
reward: '+50积分',
inviteTime: DateTime.now().subtract(const Duration(days: 1)),
),
];
_calculateTotalReward();
}
loadInviteRecords方法模拟从服务器加载邀请记录。在实际项目中,这里应该调用API接口从后端获取真实的邀请数据。方法创建了三条测试数据,包括已完成和待完成的邀请记录。玩家A和玩家C已完成首次组队,因此获得了+50积分的奖励。玩家B还未完成首次组队,所以奖励显示为"待发放"。使用DateTime.now().subtract()创建不同时间的邀请记录,用于测试时间显示功能。最后调用_calculateTotalReward()计算总奖励。
dart
void _calculateTotalReward() {
totalReward.value = inviteRecords
.where((r) => r.reward.contains('+'))
.length * 50;
}
}
_calculateTotalReward方法计算用户已获得的总奖励。使用where()方法过滤出reward字段包含'+'的记录,这些是已完成的邀请。然后计算这些记录的数量,乘以50(每个邀请的奖励积分)得到总奖励。这个方法在loadInviteRecords之后调用,确保totalReward始终与inviteRecords保持同步。
邀请页面UI实现
dart
class InvitePage extends StatelessWidget {
InvitePage({super.key});
final InviteController controller = Get.put(InviteController());
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('邀请好友'),
backgroundColor: const Color(0xFF6B4EFF),
foregroundColor: Colors.white,
elevation: 0,
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(20),
child: Column(
children: [
InvitePage是一个StatelessWidget,使用Get.put(InviteController())在页面加载时创建并注入控制器。Scaffold提供了基本的页面结构。AppBar使用紫色背景(0xFF6B4EFF),与应用的主题色保持一致。foregroundColor设置为白色,使标题和图标在紫色背景上清晰可见。elevation: 0移除AppBar的阴影效果,使界面更加扁平化。body使用SingleChildScrollView包装,支持页面内容的滚动,防止内容超出屏幕时被截断。
dart
// 邀请奖励卡片
Container(
padding: const EdgeInsets.all(24),
decoration: BoxDecoration(
gradient: const LinearGradient(
colors: [Color(0xFF6B4EFF), Color(0xFF9D4EDD)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
borderRadius: BorderRadius.circular(16),
boxShadow: [
BoxShadow(
color: const Color(0xFF6B4EFF).withOpacity(0.3),
blurRadius: 12,
offset: const Offset(0, 4),
),
],
),
child: Column(
children: [
const Icon(Icons.card_giftcard, size: 60, color: Colors.white),
const SizedBox(height: 16),
const Text(
'邀请好友 各得50积分',
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 8),
const Text(
'好友首次组队后双方各得奖励',
style: TextStyle(color: Colors.white70, fontSize: 14),
),
const SizedBox(height: 20),
邀请奖励卡片是页面的核心视觉元素。使用LinearGradient创建从紫色到粉紫色的渐变背景,从左上到右下的方向增加了视觉的动感。borderRadius: 16创建圆角效果,使卡片看起来更加现代。boxShadow添加了阴影效果,使卡片在背景上更加突出,增强了立体感。卡片内容包括一个礼物图标(Icons.card_giftcard),大小为60像素,颜色为白色。下方是邀请奖励的标题"邀请好友 各得50积分",使用大字体(20)和加粗显示,吸引用户注意。最后是对奖励规则的说明"好友首次组队后双方各得奖励",使用较小的字体和半透明白色(Colors.white70)显示。
dart
// 邀请码
Container(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Obx(() => Text(
controller.inviteCode.value,
style: const TextStyle(
color: Color(0xFF6B4EFF),
fontWeight: FontWeight.bold,
fontSize: 18,
letterSpacing: 2,
),
)),
const SizedBox(width: 12),
GestureDetector(
onTap: () {
Get.snackbar('复制成功', '邀请码已复制到剪贴板');
},
child: const Icon(Icons.copy, color: Color(0xFF6B4EFF)),
),
],
),
),
],
),
),
const SizedBox(height: 24),
邀请码容器使用白色背景,与渐变卡片形成强烈的对比。padding设置为水平20、垂直12,为邀请码提供充足的空间。borderRadius: 8创建轻微的圆角效果。Row布局包含邀请码文本和复制按钮。使用Obx包装邀请码文本,使其能够响应controller.inviteCode的变化,当邀请码更新时UI会自动刷新。letterSpacing: 2增加字符间距,使邀请码更加易读,特别是在用户手动输入时。复制按钮使用GestureDetector实现点击事件,点击时显示"复制成功"的Snackbar提示。在实际项目中,应该使用Clipboard.setData()将邀请码复制到系统剪贴板。
dart
// 分享方式
Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 8,
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'分享方式',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
),
const SizedBox(height: 16),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_shareBtn(Icons.wechat, '微信', Colors.green),
_shareBtn(Icons.qr_code, '二维码', const Color(0xFF6B4EFF)),
_shareBtn(Icons.link, '复制链接', Colors.orange),
],
),
],
),
),
const SizedBox(height: 24),
分享方式容器使用白色背景和轻微的阴影效果。padding: 16为容器内容提供充足的空间。boxShadow使用黑色半透明(0.05)创建细微的阴影,增加卡片的层次感。容器内包含一个标题"分享方式"和三个分享按钮。Row使用mainAxisAlignment: MainAxisAlignment.spaceEvenly均匀分布三个按钮,使它们之间的间距相等。三个分享按钮分别对应微信(绿色)、二维码(紫色)和复制链接(橙色)。每个按钮使用不同的颜色来区分,帮助用户快速识别。
dart
// 邀请统计
Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 8,
),
],
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
_statItem('邀请人数', Obx(() => Text(
'${controller.inviteRecords.length}',
style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold, color: Color(0xFF6B4EFF)),
))),
_statItem('已获奖励', Obx(() => Text(
'${controller.totalReward.value}积分',
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold, color: Colors.green),
))),
],
),
),
const SizedBox(height: 24),
邀请统计容器显示两个关键的统计数据:邀请人数和已获奖励。使用Row布局两个统计项,mainAxisAlignment: MainAxisAlignment.spaceAround使它们均匀分布。邀请人数使用Obx包装,动态显示inviteRecords列表的长度。已获奖励也使用Obx包装,动态显示totalReward的值。邀请人数使用大字体(24)和紫色显示,强调这个数据的重要性。已获奖励使用绿色显示,绿色通常代表积极的、有益的信息。这两个统计数据帮助用户快速了解自己的邀请成果。
dart
// 邀请记录
Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 8,
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'邀请记录',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
),
const SizedBox(height: 16),
Obx(() => ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: controller.inviteRecords.length,
itemBuilder: (context, index) {
final record = controller.inviteRecords[index];
return _recordItem(record);
},
)),
],
),
),
],
),
),
);
}
邀请记录容器展示所有的邀请记录列表。使用ListView.builder动态构建邀请记录列表,这样可以高效地处理大量的邀请记录。使用Obx包装ListView,使其能够响应inviteRecords的变化。当新的邀请记录添加时,ListView会自动刷新。shrinkWrap: true使ListView只占据必要的高度,不会占据整个屏幕。physics: const NeverScrollableScrollPhysics()禁用ListView的滚动,因为整个页面已经使用SingleChildScrollView支持滚动。itemCount设置为inviteRecords的长度,itemBuilder为每条记录调用_recordItem方法构建UI。
dart
Widget _shareBtn(IconData icon, String label, Color color) {
return GestureDetector(
onTap: () {
Get.snackbar('分享', '正在分享到$label');
},
child: Column(
children: [
Container(
width: 56,
height: 56,
decoration: BoxDecoration(
color: color.withOpacity(0.1),
borderRadius: BorderRadius.circular(28),
),
child: Icon(icon, color: color, size: 28),
),
const SizedBox(height: 8),
Text(label, style: const TextStyle(fontSize: 12)),
],
),
);
}
_shareBtn方法构建分享按钮。使用GestureDetector实现点击事件,点击时显示分享提示。Column布局包含一个圆形容器和标签文本。圆形容器使用color.withOpacity(0.1)创建浅色背景,使按钮看起来更加柔和。borderRadius: 28使容器成为完美的圆形(宽高都是56)。Icon使用传入的icon参数和color参数,大小为28。标签文本显示分享方式的名称,使用较小的字体(12)。这个方法的设计使得添加新的分享方式非常简单,只需要调用_shareBtn方法并传入相应的参数即可。
dart
Widget _statItem(String label, Widget value) {
return Column(
children: [
Text(label, style: TextStyle(color: Colors.grey[600], fontSize: 12)),
const SizedBox(height: 8),
value,
],
);
}
Widget _recordItem(InviteRecord record) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 12),
child: Row(
children: [
const CircleAvatar(
radius: 20,
backgroundColor: Color(0xFF6B4EFF),
child: Icon(Icons.person, size: 20, color: Colors.white),
),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
record.userName,
style: const TextStyle(fontWeight: FontWeight.w500, fontSize: 14),
),
Text(
record.status,
style: TextStyle(color: Colors.grey[600], fontSize: 12),
),
],
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
record.reward,
style: TextStyle(
color: record.reward.contains('+') ? Colors.green : Colors.grey,
fontWeight: FontWeight.bold,
fontSize: 14,
),
),
Text(
'${record.inviteTime.month}月${record.inviteTime.day}日',
style: TextStyle(color: Colors.grey[500], fontSize: 11),
),
],
),
],
),
);
}
}
_statItem方法构建统计项,包含标签和数值。标签使用灰色较小字体显示,数值使用传入的Widget参数显示,这样可以灵活地显示不同类型的数值。_recordItem方法构建邀请记录项。使用Row布局包含用户头像、用户信息和奖励信息。CircleAvatar创建圆形头像,使用紫色背景和人物图标。用户信息部分使用Column显示用户名和邀请状态。奖励信息部分显示奖励和邀请时间。已完成的邀请(reward包含'+')显示绿色奖励,待完成的邀请显示灰色。这个设计使得用户可以一目了然地了解每条邀请的状态和奖励。
技术要点
- 渐变背景卡片:使用LinearGradient创建吸引眼球的邀请卡片,增加视觉层次感。渐变效果从左上到右下,创建了动感的视觉效果
- 邀请码设计:letterSpacing增加字符间距,提升可读性,复制功能方便用户分享。邀请码是邀请功能的核心,需要确保其易读性和易复制性
- 分享按钮组:统一的圆形图标按钮设计,支持多种分享渠道。不同的颜色帮助用户快速识别不同的分享方式
- 记录状态区分:通过颜色区分已完成和待完成状态,提升用户体验。绿色表示已完成,灰色表示待完成,直观易懂
- 响应式更新:使用Obx实现数据的实时更新,提升应用的交互性。当数据变化时,UI会自动刷新,无需手动调用setState
小结
本篇实现了邀请好友功能,展示邀请奖励、邀请码和分享方式,记录邀请状态,激励用户分享推广App。通过多种分享渠道和清晰的邀请记录,提升用户的邀请积极性。邀请功能是用户增长的重要驱动力,合理的奖励机制和便捷的分享方式可以显著提升邀请的转化率。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net