Flutter 颤振延迟动画代码错误:在AnimationController.dispose()之后调用AnimationController.forward()

Flutter 颤振延迟动画代码错误:在AnimationController.dispose()之后调用AnimationController.forward(),flutter,dart,Flutter,Dart,我在欢迎屏幕中实现了一个延迟的动画,但我在我的颤振应用程序中得到了以下错误。如果我的代码中有错误,请告诉我,我可以更正并修复此问题 错误是: E/flatter(11565):[错误:flatter/lib/ui/ui\u dart\u state.cc(157)] 未处理的异常: “包:颤振/src/animation/animation_controller.dart”:失败 断言:第455行第7位:'\u ticker!=空': 在之后调用AnimationController.forwa

我在欢迎屏幕中实现了一个延迟的动画,但我在我的颤振应用程序中得到了以下错误。如果我的代码中有错误,请告诉我,我可以更正并修复此问题

错误是:

E/flatter(11565):[错误:flatter/lib/ui/ui\u dart\u state.cc(157)] 未处理的异常: “包:颤振/src/animation/animation_controller.dart”:失败 断言:第455行第7位:'\u ticker!=空': 在之后调用AnimationController.forward() AnimationController.dispose()

这是我的密码:

class DelayedAnimation extends StatefulWidget {
final Widget child;
 final int delay;


 DelayedAnimation({@required this.child, this.delay});

 @override
  _DelayedAnimationState createState() => _DelayedAnimationState();
}

class _DelayedAnimationState extends State<DelayedAnimation>
    with TickerProviderStateMixin {
  AnimationController _controller;
  Animation<Offset> _animOffset;

  @override
    void initState() {
    super.initState();

    _controller =
        AnimationController(vsync: this, duration: Duration(milliseconds: 800));
    final curve =
        CurvedAnimation(curve: Curves.decelerate, parent: _controller);
    _animOffset =
         Tween<Offset>(begin: const Offset(0.0, 0.35), end: Offset.zero)
            .animate(curve);

    if (widget.delay == null) {
      _controller.forward();
    } else {
      Timer(Duration(milliseconds: widget.delay), () {
        _controller.forward();
       });
    }
  }

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

  @override
  Widget build(BuildContext context) {
    return FadeTransition(
      child: SlideTransition(
        position: _animOffset,
        child: widget.child,
      ),
     opacity: _controller,
    );
 }
}
class DelayedAnimation扩展了StatefulWidget{
最后一个孩子;
最终整数延迟;
DelayedAnimation({@required this.child,this.delay});
@凌驾
_DelayedAnimationState createState()=>_DelayedAnimationState();
}
类_DelayedAnimationState扩展状态
使用TickerProviderStateMixin{
动画控制器_控制器;
动画;;
@凌驾
void initState(){
super.initState();
_控制器=
AnimationController(vsync:this,duration:duration(毫秒:800));
最终曲线=
曲线驱动(曲线:Curves.Decreate,父对象:_控制器);
_动物补偿=
吐温(开始:常数偏移(0.0,0.35),结束:偏移.0)
.制作(曲线)动画;
if(widget.delay==null){
_controller.forward();
}否则{
计时器(持续时间(毫秒:widget.delay),(){
_controller.forward();
});
}
}
@凌驾
无效处置(){
super.dispose();
_controller.dispose();
}
@凌驾
小部件构建(构建上下文){
返回衰减转换(
子:幻灯片转换(
位置:,
child:widget.child,
),
不透明度:_控制器,
);
}
}

您尚未提供所使用的
计时器的相关信息,因此无法对代码中可能出现的错误进行评论

但是我尝试使用
Future.delayed
来延迟动画,对我来说效果很好

Future.delayed(Duration(milliseconds: widget.delay), () {
        _controller.forward();
      });
希望这对你有帮助

编辑:

“(股票代码)”null”:在之后调用AnimationController.forward() AnimationController.dispose()


错误显示,
forward()
dispose()
之后调用。如果您在延迟到期前转到另一个屏幕并触发
\u controller.forward()
,则可能会发生这种情况。转到另一个屏幕会导致
\u contoller.dispose()
,因此在此之后调用
\u controller.forward()
会导致错误,因为
\u controller
已被释放。例如,如果应用程序将在1秒后进入下一个屏幕,动画延迟为2秒,则可能发生这种情况。

当您使用
计时器或
未来时,此问题通常会发生。延迟的
动画控制器进行交互。这就是问题所在。假设
delay=1000

下面的代码告诉flatter,在1000毫秒内,在
DelayedAnimation
小部件中的动画控制器上调用
forward()

Timer(Duration(milliseconds: widget.delay), () {
   _controller.forward();
});
但是,在此之前,您的
DelayedAnimation
小部件被释放(例如,如果用户移动到不同的屏幕,就会发生这种情况)

这意味着当
计时器执行时,它正在对已释放的控制器调用
forward()
(因为
DelayedAnimation
已被释放)

有几种解决办法

  • 在调用前,请检查
    已装入的
    属性:
  • 或2。创建计时器时存储计时器:

    _timer = Timer(
      Duration(
        milliseconds: widget.delay
      ), 
      () {
        _controller.forward();
      }
    );
    
    然后在dispose上取消它:

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

    你能给我你试过的完整代码吗?我仍然无法修复此问题。我不认为共享完整代码会有所帮助。因为它是相同的代码,唯一的区别是我用Future.delayed()编写的代码。事实上,您尝试了Future.delayed()但它不起作用,这意味着原因在其他地方。我将编辑答案并添加另一个要查找的内容,我认为这可能是问题所在。如果有帮助,请告诉我。我已经发布了实现页面,如果其中有任何错误导致出现错误,请告诉我。@Jyo我使用了完全相同的实现进行了尝试,它与我的工作非常好。我甚至看到了动画,在大约15秒后(如代码中设置的),应用程序也会毫无错误地过渡到下一个屏幕。感谢您的帮助。但出于某种原因,我的代码中并没有出现这个错误。我完全重写了代码,但错误仍然是一样的。谢谢你,詹姆斯·艾伦。这有帮助。“我的错误现在消失了。”詹姆斯,这些都是解决这个问题的好办法。谢谢你的回答。现在我知道如何处理这个错误,如果它曾经出现。我不理解并且令人烦恼的是——为什么会发生这种情况,当进入下一个屏幕的时间(设置为15秒)明显比两个动画时间都要长,设置为最大1100毫秒左右。我看不到任何其他原因。你知道为什么会这样吗?
    @override
      void dispose() {
        super.dispose();
        _controller.dispose();
        _timer?.cancel();
      }