颤抖动画在执行6次后停止执行

时间:2019-06-07 11:25:01

标签: flutter dart

我正在创建重复出现的缓入缓出动画,容器小部件缓入-暂停-然后缓入。我已经创建了动画,并且效果很好,但是执行6次后就停止了!我试图将第二个侦听器放入自己的方法中,然后使用removeListener,但这也没有用。 任何建议或想法将不胜感激。 这是我的代码:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(primaryColor: Colors.red),
      home: EaseAnimation(),
    );
  }
}

class EaseAnimation extends StatefulWidget {
  @override
  _EaseAnimationState createState() => _EaseAnimationState();
}

class _EaseAnimationState extends State<EaseAnimation>
    with TickerProviderStateMixin {
  Animation _animation;
  AnimationController _controller;
  @override
  void initState() {
    void listener(status) {
      if (status == AnimationStatus.completed) {
        _animation.removeStatusListener(listener);
        _controller.reset();
        _animation = Tween(begin: 0.0, end: 1.0).animate(
            CurvedAnimation(parent: _controller, curve: Curves.fastOutSlowIn))
          ..addStatusListener((status) {
            if (status == AnimationStatus.completed) {
              _controller.reset();
              _animation = Tween(begin: -1.0, end: 0.0).animate(CurvedAnimation(
                  parent: _controller, curve: Curves.fastOutSlowIn))
                ..addStatusListener(listener);
              _controller.forward();
            }
          });
      }
    }

    _controller =
        AnimationController(vsync: this, duration: Duration(seconds: 2));
    _animation = Tween(begin: -1.0, end: 0.0).animate(
        CurvedAnimation(parent: _controller, curve: Curves.fastOutSlowIn))
      ..addStatusListener(listener);
    _controller.forward();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    final double width = MediaQuery.of(context).size.width;
    return AnimatedBuilder(
      animation: _controller,
      builder: (BuildContext context, Widget child) {
        return Scaffold(
          body: Transform(
            transform:
                Matrix4.translationValues(_animation.value * width, 0.0, 0.0),
            child: Center(
                child: Container(
              height: 200,
              width: 200,
              color: Colors.black,
            )),
          ),
        );
      },
    );
  }
}

1 个答案:

答案 0 :(得分:1)

快速但具破坏性的解决方案是将if中的listener条件更改为:

if (status == AnimationStatus.completed || status == AnimationStatus.dismissed) {

但是,动画的设计方式会带来很多问题。实际上,它确实已经造成了麻烦。

动画卡住的原因是因为它将一个动画侦听器嵌套到另一个侦听器中,从而进入了Flutter试图处理的一种锁定的无限循环。


我建议使用Cubic类设计自定义动画曲线。例如

Cubic(0, 1, 1, 0)

这条简单的曲线会将动画停在其进度的中间。

现在,我们可以将您的代码修改为更简单的方式-像这样:

void listener(status) {
  if (status == AnimationStatus.completed) {
    _controller.forward(from: 0);
  }
}

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

  _controller = AnimationController(vsync: this, duration: Duration(seconds: 4));
  _animation = Tween(begin: -1.0, end: 1.0).animate(
      CurvedAnimation(parent: _controller, curve: const Cubic(0, 1, 1, 0))
    )
    ..addStatusListener(listener);

  _controller.forward();
}

这将呈现一个黑框,该黑框从左侧开始,前进到屏幕中央,暂停,然后恢复到屏幕结尾,然后重复。

如果我建议的曲线不适合您的情况-this link将帮助您设计自己的自定义曲线,并帮助您大致了解Cubic Bezier曲线。

让我知道这是否有帮助。