Flutter for OpenHarmony 剧本杀组队App实战:邀请好友功能实现

引言

邀请好友是用户增长的重要功能,通过奖励机制激励用户分享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包含'+')显示绿色奖励,待完成的邀请显示灰色。这个设计使得用户可以一目了然地了解每条邀请的状态和奖励。

技术要点

  1. 渐变背景卡片:使用LinearGradient创建吸引眼球的邀请卡片,增加视觉层次感。渐变效果从左上到右下,创建了动感的视觉效果
  2. 邀请码设计:letterSpacing增加字符间距,提升可读性,复制功能方便用户分享。邀请码是邀请功能的核心,需要确保其易读性和易复制性
  3. 分享按钮组:统一的圆形图标按钮设计,支持多种分享渠道。不同的颜色帮助用户快速识别不同的分享方式
  4. 记录状态区分:通过颜色区分已完成和待完成状态,提升用户体验。绿色表示已完成,灰色表示待完成,直观易懂
  5. 响应式更新:使用Obx实现数据的实时更新,提升应用的交互性。当数据变化时,UI会自动刷新,无需手动调用setState

小结

本篇实现了邀请好友功能,展示邀请奖励、邀请码和分享方式,记录邀请状态,激励用户分享推广App。通过多种分享渠道和清晰的邀请记录,提升用户的邀请积极性。邀请功能是用户增长的重要驱动力,合理的奖励机制和便捷的分享方式可以显著提升邀请的转化率。

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

相关推荐
yong99902 小时前
MATLAB的智能扫地机器人工作过程仿真
开发语言·matlab·机器人
浮尘笔记2 小时前
Go语言并发安全字典:sync.Map的使用与实现
开发语言·后端·golang
2301_811232982 小时前
C++中的契约编程
开发语言·c++·算法
2401_829004022 小时前
C++中的访问者模式
开发语言·c++·算法
黎雁·泠崖2 小时前
Java内部类与匿名内部类:定义+类型+实战应用
java·开发语言
青槿吖2 小时前
第二篇:JDBC进阶骚操作:防注入、事务回滚、连接池优化,一篇封神
java·开发语言·jvm·算法·自动化
赵萱婷2 小时前
C++17 nodiscard属性深度解析
开发语言·c++·经验分享
kklovecode2 小时前
C++对C语言的增强
c语言·开发语言·c++