GiftStore 是 AtomicXCore 中专门负责管理直播间礼物功能的模块。通过它,您可以为您的直播应用构建一套完整的礼物系统,实现丰富的营收和互动场景。礼物面板 | 弹幕礼物 | 全屏礼物 |
![]() | ![]() | ![]() |
GiftStore 相关的几个核心概念:核心概念 | 类型 | 核心职责与描述 |
class | 代表一个具体的礼物数据模型。包含了礼物的 ID、名称、图标地址、动画资源地址 (resourceURL) 和价格 (coins) 等。 | |
class | 代表一个礼物分类,例如“热门”、“豪华”等。它包含了分类的名称以及该分类下的 Gift 列表。 | |
class | 代表礼物模块的当前状态。其核心属性 usableGifts 是一个 ValueListenable<List<GiftCategory>>,存储了从服务端拉取到的完整礼物列表。 | |
class | 礼物事件监听器,通过 onReceiveGift 回调接收礼物赠送事件,当有任何人(包括自己)发送礼物时,房间内所有人都会收到此事件。 | |
class | 这是与礼物功能交互的核心管理类。通过它,您可以拉取礼物列表、发送礼物,并通过 addGiftListener 来接收礼物事件。 |
GiftStore 实例,并设置监听器以接收礼物事件和礼物列表更新。GiftStore.create(liveId) 获取与当前直播间绑定的 GiftStore 实例。giftStore.addGiftListener(listener) 添加礼物事件监听器。giftStore.giftState.usableGifts 获取礼物列表更新。import 'package:flutter/foundation.dart';import 'package:atomic_x_core/atomicxcore.dart';class GiftManager {final String liveId;late final GiftStore giftStore;late final GiftListener _giftListener;late final VoidCallback _giftListChangedListener = _onGiftListChanged;// 对外暴露礼物事件回调void Function(String liveID, Gift gift, int count, LiveUserInfo sender)? onReceiveGift;// 对外暴露礼物列表ValueNotifier<List<GiftCategory>> giftListNotifier = ValueNotifier([]);GiftManager({required this.liveId}) {// 1. 通过 liveId 获取 GiftStore 的实例giftStore = GiftStore.create(liveId);_subscribeToGiftState();_subscribeToGiftEvents();}/// 2. 订阅礼物事件void _subscribeToGiftEvents() {_giftListener = GiftListener(onReceiveGift: (liveID, gift, count, sender) {// 收到事件后,将其转发给外部处理onReceiveGift?.call(liveID, gift, count, sender);},);giftStore.addGiftListener(_giftListener);}/// 3. 订阅礼物列表状态void _subscribeToGiftState() {giftStore.giftState.usableGifts.addListener(_giftListChangedListener);}void _onGiftListChanged() {giftListNotifier.value = giftStore.giftState.usableGifts.value;}// 在退出直播间时可调用 dispose 方法回收资源void dispose() {giftStore.removeGiftListener(_giftListener);giftStore.giftState.usableGifts.removeListener(_giftListChangedListener);giftListNotifier.dispose();}}
GiftCategory参数说明参数 | 类型 | 描述 |
categoryID | String | 礼物分类的唯一 ID。 |
name | String | 礼物分类的显示名称。 |
desc | String | 礼物分类的描述信息。 |
extensionInfo | Map<String, String> | 扩展信息字段。 |
giftList | List<Gift> | 该分类下包含的 Gift 礼物对象数组。 |
Gift参数说明参数 | 类型 | 描述 |
giftID | String | 礼物的唯一 ID。 |
name | String | 礼物的显示名称。 |
desc | String | 礼物的描述信息。 |
iconURL | String | 礼物图标 URL。 |
resourceURL | String | 礼物动画资源 URL。 |
level | int | 礼物等级。 |
coins | int | 礼物价格。 |
extensionInfo | Map<String, String> | 扩展信息字段。 |
refreshUsableGifts 方法,从服务端拉取礼物数据。giftStore.refreshUsableGifts()。giftStore.giftState.usableGifts 的监听,自动接收到更新后的礼物列表。extension GiftManagerFetch on GiftManager {/// 从服务端刷新礼物列表Future<void> fetchGiftList() async {final result = await giftStore.refreshUsableGifts();if (result.isSuccess) {debugPrint("礼物列表拉取成功");// 成功后,数据会通过 usableGifts 监听自动更新} else {debugPrint("礼物列表拉取失败: ${result.errorMessage}");}}}
sendGift 接口将礼物发送出去。giftStore.sendGift(giftID:, count:)。onReceiveGift 事件驱动。extension GiftManagerSend on GiftManager {/// 用户发送一个礼物Future<void> sendGift(String giftID, int count) async {final result = await giftStore.sendGift(giftID: giftID, count: count);if (result.isSuccess) {debugPrint("礼物 $giftID 发送成功");// 发送成功后,包括发送者在内的所有人都会收到 onReceiveGift 事件} else {debugPrint("礼物发送失败: ${result.errorMessage}");// 可以在此提示用户,例如“余额不足”或“网络错误”}}}
sendGift 接口参数参数名 | 类型 | 描述 |
giftID | String | 要发送的礼物的唯一 ID。 |
count | int | 发送的数量。 |
GiftStore 的功能高度依赖于您的业务后台服务。本章将指导您如何通过服务端配置和客户端实现,构建功能丰富、体验卓越的礼物互动系统。refreshUsableGifts 获取配置数据。List<GiftCategory> 数据填充礼物面板。
sendGift。onReceiveGift 事件。扣费失败,sendGift 返回错误。
接口 | 说明 | 请求示例 |
回调配置 - 发送礼物之前回调 | 客户后台可以通过该回调决定是否通过送礼前校验等场景。 |
AtomicXCore 本身不包含礼物动画播放器,您需要根据业务需求选择并集成第三方库。以下是两种方案的对比:对比项 | 基础方案 (svgaplayer_flutter) | 高级方案 (TCEffectPlayerKit) |
计费 | 免费 (开源库)。 | |
集成方式 | ||
动画格式支持 | 仅支持 SVGA。 | SVGA、PAG、WebP、Lottie、MP4 等多种格式。 |
性能 | 建议 SVGA 文件 ≤ 10MB。 | 支持更大的动画文件,复杂特效/多动画并发/低端机表现更优。 |
推荐场景 | 礼物动画格式统一为 SVGA,且文件大小可控。 | 需要支持多种动画格式,或对动画性能/设备兼容性有更高要求。 |
pubspec.yaml 文件中,添加依赖并运行 flutter pub get。dependencies:svgaplayer_flutter: ^2.0.0
GiftStore 的 addGiftListener 添加监听器。onReceiveGift 事件时,检查 gift.resourceURL 是否有效且指向一个 SVGA 文件。如果是,则使用 SVGAAnimationController 播放动画。import 'package:flutter/material.dart';import 'package:atomic_x_core/atomicxcore.dart';import 'package:svgaplayer_flutter/svgaplayer_flutter.dart';class LiveRoomWidget extends StatefulWidget {final String liveId;const LiveRoomWidget({Key? key, required this.liveId}) : super(key: key);@overrideState<LiveRoomWidget> createState() => _LiveRoomWidgetState();}class _LiveRoomWidgetState extends State<LiveRoomWidget> with SingleTickerProviderStateMixin {late GiftManager giftManager;// SVGA 播放器late SVGAAnimationController _svgaController;bool _showAnimation = false;@overridevoid initState() {super.initState();_svgaController = SVGAAnimationController(vsync: this);_setupGiftSubscription();}void _setupGiftSubscription() {giftManager = GiftManager(liveId: widget.liveId);giftManager.onReceiveGift = (liveID, gift, count, sender) {if (gift.resourceURL.isNotEmpty) {_playAnimation(gift.resourceURL);}};}Future<void> _playAnimation(String url) async {try {final videoItem = await SVGAParser.shared.decodeFromURL(url);_svgaController.videoItem = videoItem;setState(() {_showAnimation = true;});_svgaController.forward().whenComplete(() {setState(() {_showAnimation = false;});});} catch (e) {debugPrint("SVGA 动画解析失败: $e");}}@overridevoid dispose() {_svgaController.dispose();giftManager.dispose();super.dispose();}@overrideWidget build(BuildContext context) {return Stack(children: [// 直播画面// ...// 全屏礼物动画if (_showAnimation)Positioned.fill(child: SVGAImage(_svgaController),),],);}}
giftStore.addGiftListener 添加监听器。onReceiveGift 事件后,提取发送者 sender、礼物 gift 和数量 count。BarrageStore.create(liveId) 获取与当前房间绑定的实例。Barrage 对象,设置 messageType = BarrageType.text,textContent 为拼接好的字符串(例如 “[sender.userName] 送出了 [gift.name] x [count]”)。barrageStore.appendLocalTip(giftTip) 将消息插入本地列表。// 在 LiveRoomManager 或类似的顶层管理器中void _setupGiftToBarrageFlow() {final giftStore = GiftStore.create(liveId);final barrageStore = BarrageStore.create(liveId);final giftListener = GiftListener(onReceiveGift: (liveID, gift, count, sender) {// 拼接消息final tipText = "${sender.userName} 送出了 ${gift.name} x $count";final giftTip = Barrage(messageType: BarrageType.text,textContent: tipText,);// 可选:设置一个特殊的sender// 本地插入barrageStore.appendLocalTip(giftTip);},);giftStore.addGiftListener(giftListener);}
GiftStore 的礼物列表是空的,我该怎么办?refreshUsableGifts() 来从您的业务后台拉取礼物数据。这些礼物数据需要在您的业务后台通过服务端 REST API 进行配置。GiftStore 提供了 setLanguage(String language) 接口。您可以在 refreshUsableGifts 之前调用此方法,传入目标语言代码(例如 “en” 或 “zh-CN”)。服务端会根据此语言代码,返回对应语言的礼物名称和描述。onReceiveGift 事件是对房间内所有成员的广播(包括发送者自己)。如果您在 sendGift 的成功回调里执行了一次 UI 操作,同时又在 onReceiveGift 回调中执行了相同的 UI 操作,就会造成重复。onReceiveGift 事件的回调中处理。sendGift 的返回结果仅用于处理发送失败的逻辑(例如提示用户“发送失败”或“余额不足”)。AtomicXCore 通过后台回调机制与您的计费系统对接。客户端调用 sendGift 触发回调,您的后台服务完成扣费后,将结果返回给 AtomicXCore 后台,从而决定礼物事件是否广播。onReceiveGift 事件)不受禁言或消息频控影响,确保可靠投递。Apakah halaman ini membantu?
Anda juga dapat Menghubungi Penjualan atau Mengirimkan Tiket untuk meminta bantuan.
masukan