我正在创建重复出现的缓入缓出动画,容器小部件缓入-暂停-然后缓入。我已经创建了动画,并且效果很好,但是执行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,
)),
),
);
},
);
}
}
答案 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曲线。
让我知道这是否有帮助。