在Flutter中重播相同的Flare动画

时间:2019-03-22 14:15:39

标签: flutter flutter-layout flutter-animation flare

我正在尝试在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

所有内容都被调用,它是第一次播放,但是此后不会重播动画。

3 个答案:

答案 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”参数。

此处的完整示例:https://github.com/luigi-rosso/flare_controls

答案 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;

                         });
                       }
                      },
                    )