-
Notifications
You must be signed in to change notification settings - Fork 222
Description
When I play the rive animation in flutter, a mosaic like this will appear:
My widget code is as follows:
`
import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
import 'package:rive/rive.dart';
import '../../models/treasure_chest_model.dart';
import '../../models/item_model.dart';
class TreasureRiveWidget extends StatefulWidget {
final String asset;
final double width;
final double height;
final String stateMachineName; // 默认状态机名称为 'main'
final ChestRewardResult reward; // 外部传入的奖励
const TreasureRiveWidget({
Key? key,
required this.asset,
required this.reward,
this.width = 100,
this.height = 100,
this.stateMachineName = 'main',
}) : super(key: key);
@OverRide
TreasureRiveWidgetState createState() => TreasureRiveWidgetState();
}
class TreasureRiveWidgetState extends State {
Artboard? _artboard;
SMINumber? _itemId;
bool _destroyed = false;
bool isFinish = false; // 外部可查看动画是否结束
@OverRide
void initState() {
super.initState();
// 加载 Rive 动画文件
rootBundle.load(widget.asset).then((data) async {
final file = RiveFile.import(data);
final artboard = file.mainArtboard.instance();
// 添加状态机控制器(若状态机存在)
var controller = StateMachineController.fromArtboard(
artboard,
widget.stateMachineName,
);
// 添加状态机控制器并获取 itemId 输入
if (controller != null) {
artboard.addController(controller);
_itemId = controller.getNumberInput('itemId');
}
// 根据外部传入的奖励决定宝箱开出物品动画
if (widget.reward is ItemReward) {
final itemReward = widget.reward as ItemReward;
switch (itemReward.itemType) {
case ItemType.p1:
_itemId?.value = 2;
break;
case ItemType.p2:
_itemId?.value = 7;
break;
case ItemType.p3:
_itemId?.value = 3;
break;
case ItemType.p4:
_itemId?.value = 1;
break;
case ItemType.p5:
_itemId?.value = 8;
break;
case ItemType.p6:
_itemId?.value = 4;
break;
}
} else if (widget.reward is CoinReward) {
_itemId?.value = 9;
} else if (widget.reward is KeyReward) {
_itemId?.value = 6;
} else if (widget.reward is DiamondReward) {
_itemId?.value = 5;
}
controller?.addEventListener(onRiveEvent);
// 设置 artboard 更新UI
setState(() {
_artboard = artboard;
});
});
}
void onRiveEvent(RiveEvent event) {
if (event.name == 'eFinish') {
// 增加一秒的延迟
Future.delayed(const Duration(seconds: 1), () {
// 设置 destroyed 为 true 表示动画结束
setState(() {
_destroyed = true;
});
});
}
}
@OverRide
void didUpdateWidget(covariant TreasureRiveWidget oldWidget) {
super.didUpdateWidget(oldWidget);
}
bool getIsFinsh() {
return _destroyed;
}
/// 对外公开的方法,允许父组件更新 _plopInput 的值
void updatePlopValue(double value) {
_itemId?.value = value;
}
@OverRide
Widget build(BuildContext context) {
if (_destroyed) {
return Container();
}
return SizedBox(
width: widget.width,
height: widget.height,
child: _artboard != null
? Rive(
artboard: _artboard!,
)
: Container(),
);
}
}
// 构建奖励详情
Widget _buildRewardDetails(ChestRewardResult reward) {
if (reward is ItemReward) {
return Text("获得了1个${reward.itemName}!");
} else if (reward is CoinReward) {
return Text("获得了${reward.amount}金币!");
} else if (reward is KeyReward) {
return Text("获得了${reward.amount}把钥匙!");
} else if (reward is DiamondReward) {
return Text("获得了${reward.amount}颗钻石!");
} else {
return const Text("获得了未知奖励!");
}
}
`

