我正在尝试在Flutter中重新播放Flare动画。完成后不循环播放动画。我希望按需播放相同的动画。
当我在动画之间切换时,仅交换字符串并调用setState即可正常工作。有没有简单的方法可以做到这一点。
这就是我目前正在做的事情。
class _FlareDemoState extends State<FlareDemo> {
String animationToPlay = 'activate';
@override
Widget build(BuildContext context) {
print('Animation to play: $animationToPlay');
return Scaffold(
backgroundColor: Colors.purple,
body: GestureDetector(
onTap: () {
setState(() {
});
},
child: FlareActor('assets/button-animation.flr',
animation: animationToPlay)));
}
}
点击动画时,我的日志结果
I/flutter (18959): Animation to play: activate
I/flutter (18959): Animation to play: activate
I/chatty (18959): uid=10088(com.example.flare_tutorial) Thread-2 identical 2 lines
I/flutter (18959): Animation to play: activate
I/flutter (18959): Animation to play: activate
I/chatty (18959): uid=10088(com.example.flare_tutorial) Thread-2 identical 7 lines
I/flutter (18959): Animation to play: activate
I/flutter (18959): Animation to play: activate
Reloaded 2 of 495 libraries in 672ms.
I/flutter (18959): Animation to play: activate
所有内容都被调用,它是第一次播放,但是此后不会重播动画。
答案 0 :(得分:2)
更干净的方法是使用自定义FlareController。有一个具体的FlareControls实现非常适合此用例。
class _MyHomePageState extends State<MyHomePage> {
// Store a reference to some controls for the Flare widget
final FlareControls controls = FlareControls();
void _playSuccessAnimation() {
// Use the controls to trigger an animation.
controls.play("success");
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: FlareActor("assets/Teddy.flr",
animation: "idle",
fit: BoxFit.contain,
alignment: Alignment.center,
// Make sure you use the controls with the Flare Actor widget.
controller: controls),
floatingActionButton: FloatingActionButton(
onPressed: _playSuccessAnimation,
tooltip: 'Play',
child: Icon(Icons.play_arrow),
),
);
}
}
请注意,此示例还播放循环的空闲背景动画。对FlareControls.play的任何调用都将在此背景空闲动画上混合传入的动画。如果您不希望/不需要背景动画,则只需忽略动画:“ idle”参数。
答案 1 :(得分:0)
根据@Eugene的回答,我提出了一个临时解决方案。我将该值设置为空,启动计时器50ms,然后将该值设置回我想再次播放的动画。
class _FlareDemoState extends State<FlareDemo> {
String animationToPlay = 'activate';
@override
Widget build(BuildContext context) {
print('Animation to play: $animationToPlay');
return Scaffold(
backgroundColor: Colors.purple,
body: GestureDetector(
onTap: () {
_setAnimationToPlay('activate');
},
child: FlareActor('assets/button-animation.flr',
animation: animationToPlay)));
}
}
void _setAnimationToPlay(String animation) {
if (animation == _animationToPlay) {
_animationToPlay = '';
Timer(const Duration(milliseconds: 50), () {
setState(() {
_animationToPlay = animation;
});
});
} else {
_animationToPlay = animation;
}
}
这是一个凌乱的解决方法,但可以完成工作。谢谢@Eugene播种。
答案 2 :(得分:0)
FlareActor(
"assets/animation/day_night.flr",
alignment: Alignment.center,
fit: BoxFit.cover,
animation: _animation,
callback: (string) {
if(string=="switch_night"){
setState(() {
_animation = _animationNight;
});
}else if(string=="switch_day"){
setState(() {
_animation = _animationDay;
});
}
},
)