监听动画完成事件

7

我想在我的动画完成后执行一个操作。我尝试添加statusListener,但对我来说没有用。我的代码如下:

  @override
  void initState() {
    super.initState();
    _controller = new AnimationController(
      duration: new Duration(milliseconds: 500),
      vsync: this,
    )..addStatusListener((AnimationStatus status) {
      print("Going");
      if (status.index == 3 && spins > 0) { // AnimationStatus index 3 == completed animation
        _controller.duration = new Duration(milliseconds: speed - 50);
        _controller.forward(from: _controller.value == null ? 0.0 : 1 - _controller.value);
        spins--;
        print(speed);
      }
    });
  }
print(Going);没有被执行,但我的动画确实已经结束了。出了什么问题?
///---编辑---///
我正在使用AnimatedBuilder,代码的这一部分看起来像这样:
child: new AnimatedBuilder(
  animation: _controller,
  child: new Image.network(widget.url),
  builder: (BuildContext context, Widget child) {
    return new Transform.rotate(
      angle: _controller.value * 2.0 * math.PI,
      child: child,
    );
  },
),
3个回答

12

针对您的评论和编辑,我研究了AnimationBuilder。通过调整文档中的示例,我得出了这个可行的解决方案:

class Spinner extends StatefulWidget {
  @override
  _SpinnerState createState() => new _SpinnerState();
}

class _SpinnerState extends State<Spinner> with SingleTickerProviderStateMixin {
  AnimationController _controller;
  CurvedAnimation _animation;

  @override
  void initState() {
    super.initState();
    _controller = new AnimationController(
      duration: const Duration(seconds: 5),
      vsync: this,
    )..forward();

    _animation = new CurvedAnimation(
        parent: _controller,
        curve: Curves.linear,
    )..addStatusListener((AnimationStatus status) {
      if (status == AnimationStatus.completed)
        print('completed');
    });
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return new AnimatedBuilder(
      animation: _animation,
      child: new Container(width: 200.0, height: 200.0, color: Colors.green),
      builder: (BuildContext context, Widget child) {
        return new Transform.rotate(
          angle: _controller.value * 2.0 * 3.1415,
          child: child,
        );
      },
    );
  }
}

正如您所看到的,我将控制器用作动画的父级,然后将其用作AnimationBuilder的动画。希望有所帮助。


5

您还可以使用whenComplete监听器

_animationController.forward().whenComplete((){
     //Trigger different responses, when animation is started at different places.
})

4

参考flutter gallery中的进度指示器示例,您应该将StatusListener附加到动画而不是控制器。

_controller = AnimationController(
  duration: const Duration(milliseconds: 1500),
  vsync: this,
)..forward();

_animation = CurvedAnimation(
  parent: _controller,
  curve: const Interval(0.0, 0.9, curve: Curves.fastOutSlowIn),
  reverseCurve: Curves.fastOutSlowIn
)..addStatusListener((AnimationStatus status) {
  if (status == AnimationStatus.dismissed)
    _controller.forward();
  else if (status == AnimationStatus.completed)
    _controller.reverse();
});

我没有使用你的代码进行测试。如果不起作用,请告诉我;)


我忘了说我正在使用 AnimatedBuilder(我编辑了帖子并添加了一些代码)。我不认为我可以将你的方法应用到我所写的内容上,还有其他想法吗? - Bram Vanbilsen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接