首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >颤振延迟动画代码错误: AnimationController.forward()在AnimationController.dispose()之后调用

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

Stack Overflow用户
提问于 2020-07-04 08:17:31
回答 2查看 8.3K关注 0票数 6

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

错误是:

代码语言:javascript
复制
E/flutter (11565): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)]
Unhandled Exception:
'package:flutter/src/animation/animation_controller.dart': Failed
assertion: line 455 pos 7: '_ticker != null':
AnimationController.forward() called after
AnimationController.dispose()

这是我的代码:

代码语言:javascript
复制
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,
    );
  }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-07-13 09:14:09

当您使用TimerFuture.delayedAnimationController交互时,经常会出现此问题。这就是问题所在。让我们说,delay = 1000

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

代码语言:javascript
复制
Timer(Duration(milliseconds: widget.delay), () {
   _controller.forward();
});

然而,在此之前,您的DelayedAnimation小部件将被释放(例如,如果用户移动到另一个屏幕,就会发生这种情况)。

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

有几个解决办法。

  1. 在调用前检查mounted属性:

代码语言:javascript
复制
Timer(
  Duration(
    milliseconds: widget.delay
  ), 
  () {
    if(mounted) {
      _controller.forward();
    }
  }
);

或者2.在创建计时器时存储它:

代码语言:javascript
复制
_timer = Timer(
  Duration(
    milliseconds: widget.delay
  ), 
  () {
    _controller.forward();
  }
);

然后在处分时取消它:

代码语言:javascript
复制
@override
  void dispose() {
    super.dispose();
    _controller.dispose();
    _timer?.cancel();
  }
票数 19
EN

Stack Overflow用户

发布于 2020-07-04 08:38:00

您没有提供您使用过的Timer的信息,因此不能评论您的代码中可能出错的地方。

但是我试着用Future.delayed来延迟动画,它对我来说很好。

代码语言:javascript
复制
Future.delayed(Duration(milliseconds: widget.delay), () {
        _controller.forward();
      });

希望这能帮到你。

编辑:

'_ticker != null':在AnimationController.dispose()之后调用AnimationController.forward()

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62726872

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档