多个 Flutter 动画一个接一个地不起作用
Multiple Flutter animation not working one after the other
我是 flutter 的新手,目前我正在尝试制作一个简单的应用程序,当应用程序打开时,文本会出现 fadeIn
并更改其 position from bottom to top
。是的,有两个 animations
我想要 Transit
。第一个是 FadeIn
完成后继续进行下一个 animation
即 Position Transition
将文本的 Vertical
位置从 400.0
更改至 200.0 pixels.
我能够实现淡入过程,但没有应用第一个位置。
首先,我希望 FadeIn TextAnimation 在完成后启动我想启动 PositionAnimation,不是同时启动,而是在动画完成后一个接一个地启动。
代码如下:
class _SplashScreenState extends State<SplashScreen>
with TickerProviderStateMixin {
AnimationController animationController;
double position = 400.0;
Animation<double> _animation;
Tween<double> tween;
@override
void initState() {
super.initState();
animationController = AnimationController(
vsync: this,
duration: Duration(milliseconds: 700),
);
_animation = CurvedAnimation(
parent: animationController,
curve: Curves.easeIn,
);
tween = Tween(begin: 400, end: 200);
animationController.forward();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.amber,
body: FadeTransition(
opacity: _animation,
child: Padding(
padding: EdgeInsets.symmetric(
vertical:_animation.isCompleted? tween : position,
horizontal: 180.0),
child: Text(
'My Life',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 30.0,
color: Colors.white70,
letterSpacing: 2.0),
),
),
),
);
}
@override
void dispose() {
animationController.dispose();
super.dispose();
}
}
任何专业知识,因为我是新手,所以我不确定我做错了什么。请指导我,任何人。
这是我今天尝试过但仍然没有得到结果的更新代码:
class _SplashScreenState extends State<SplashScreen>
with TickerProviderStateMixin {
AnimationController animationControllerFade;
AnimationController animationControllerPost;
double position = 400.0;
FadeTransition fadeTransition;
Animation<double> animation;
int i = 0;
@override
void initState() {
super.initState();
animationControllerFade = AnimationController(
vsync: this,
duration: Duration(milliseconds: 700),
);
animationControllerPost = AnimationController(
vsync: this,
duration: Duration(milliseconds: 700),
);
animation = CurvedAnimation(
parent: animationControllerFade,
curve: Curves.easeIn,
);
animationControllerFade.forward();
}
@override
Widget build(BuildContext context) {
Scaffold sc;
sc = Scaffold(
backgroundColor: Colors.amber,
);
fadeTransition = FadeTransition(
opacity: animation,
child: paddingOwn(position),
);
animationControllerFade.addStatusListener((status) {
if (status == AnimationStatus.completed) {
animationControllerPost.forward();
sc = Scaffold(
body: TweenAnimationBuilder(
curve: Curves.easeIn,
duration: Duration(milliseconds: 700),
tween: Tween<double>(begin: 400.0, end: 200.0),
builder: (BuildContext context, double val, Widget child) {
return Positioned(child: paddingOwn(val));
},
),
);
}
else {
sc = Scaffold(body: fadeTransition);
}
});
return sc;
}
Widget paddingOwn(double val) {
return Padding(
padding: EdgeInsets.symmetric(
vertical: val,
horizontal: 180,
),
child: Text(
'My Life',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 30.0,
color: Colors.white70,
letterSpacing: 2.0),
),
);
}
@override
void dispose() {
animationControllerFade.dispose();
animationControllerPost.dispose();
super.dispose();
}
}
仍然没有结果。
如果要获取位置转换,需要使用SlideTransition
。
此外,您需要为 Tween
设置动画,以便正确插值。
我稍微更改了您的代码,以便将文本居中并从那里设置动画。无论如何,请记住 SlideTransition
适用于 Offsets in a relative way from the size of the child
现在,您应该能够根据您想要实现的最终结果调整此代码:
class _SplashScreenState extends State<SplashScreen> with TickerProviderStateMixin {
AnimationController _fadeAnimationController;
AnimationController _slideAnimationController;
double position = 400.0;
Animation<double> _fadeAnimation;
Animation<Offset> _slideAnimation;
@override
void initState() {
super.initState();
_fadeAnimationController = AnimationController(
vsync: this,
duration: Duration(milliseconds: 700),
);
_slideAnimationController = AnimationController(
vsync: this,
duration: Duration(milliseconds: 700),
);
_fadeAnimation = CurvedAnimation(
parent: _fadeAnimationController,
curve: Curves.easeIn,
);
_slideAnimation = Tween(begin: Offset(0, 0), end: Offset(0, -3)).animate(CurvedAnimation(
parent: _slideAnimationController,
curve: Curves.easeInOut,
));
_play();
}
Future<void> _play() async {
try {
await _fadeAnimationController.forward().orCancel;
await _slideAnimationController.forward().orCancel;
} on TickerCanceled {
//Handle if animation was canceled for whatever reason if you need it
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.amber,
body: Center(
child: SlideTransition(
position: _slideAnimation,
child: FadeTransition(
opacity: _fadeAnimation,
child: Text(
'My Life',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30.0, color: Colors.white70, letterSpacing: 2.0),
),
),
),
),
);
}
@override
void dispose() {
_fadeAnimationController.dispose();
_slideAnimationController.dispose();
super.dispose();
}
}
更新:
您没有看到填充的变化,因为您有两个错误:
- 您没有为补间设置动画
- 您正在使用
symmetric
,从两侧添加相同的边距。
要解决补间问题,您需要添加如下内容:
tween = Tween(begin: 400, end: 200).animate(animationController);
要解决填充问题,您可以使用 only
,仅在一侧应用 填充:
padding: EdgeInsets.only(top: tween)
我是 flutter 的新手,目前我正在尝试制作一个简单的应用程序,当应用程序打开时,文本会出现 fadeIn
并更改其 position from bottom to top
。是的,有两个 animations
我想要 Transit
。第一个是 FadeIn
完成后继续进行下一个 animation
即 Position Transition
将文本的 Vertical
位置从 400.0
更改至 200.0 pixels.
我能够实现淡入过程,但没有应用第一个位置。 首先,我希望 FadeIn TextAnimation 在完成后启动我想启动 PositionAnimation,不是同时启动,而是在动画完成后一个接一个地启动。
代码如下:
class _SplashScreenState extends State<SplashScreen>
with TickerProviderStateMixin {
AnimationController animationController;
double position = 400.0;
Animation<double> _animation;
Tween<double> tween;
@override
void initState() {
super.initState();
animationController = AnimationController(
vsync: this,
duration: Duration(milliseconds: 700),
);
_animation = CurvedAnimation(
parent: animationController,
curve: Curves.easeIn,
);
tween = Tween(begin: 400, end: 200);
animationController.forward();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.amber,
body: FadeTransition(
opacity: _animation,
child: Padding(
padding: EdgeInsets.symmetric(
vertical:_animation.isCompleted? tween : position,
horizontal: 180.0),
child: Text(
'My Life',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 30.0,
color: Colors.white70,
letterSpacing: 2.0),
),
),
),
);
}
@override
void dispose() {
animationController.dispose();
super.dispose();
}
}
任何专业知识,因为我是新手,所以我不确定我做错了什么。请指导我,任何人。
这是我今天尝试过但仍然没有得到结果的更新代码:
class _SplashScreenState extends State<SplashScreen>
with TickerProviderStateMixin {
AnimationController animationControllerFade;
AnimationController animationControllerPost;
double position = 400.0;
FadeTransition fadeTransition;
Animation<double> animation;
int i = 0;
@override
void initState() {
super.initState();
animationControllerFade = AnimationController(
vsync: this,
duration: Duration(milliseconds: 700),
);
animationControllerPost = AnimationController(
vsync: this,
duration: Duration(milliseconds: 700),
);
animation = CurvedAnimation(
parent: animationControllerFade,
curve: Curves.easeIn,
);
animationControllerFade.forward();
}
@override
Widget build(BuildContext context) {
Scaffold sc;
sc = Scaffold(
backgroundColor: Colors.amber,
);
fadeTransition = FadeTransition(
opacity: animation,
child: paddingOwn(position),
);
animationControllerFade.addStatusListener((status) {
if (status == AnimationStatus.completed) {
animationControllerPost.forward();
sc = Scaffold(
body: TweenAnimationBuilder(
curve: Curves.easeIn,
duration: Duration(milliseconds: 700),
tween: Tween<double>(begin: 400.0, end: 200.0),
builder: (BuildContext context, double val, Widget child) {
return Positioned(child: paddingOwn(val));
},
),
);
}
else {
sc = Scaffold(body: fadeTransition);
}
});
return sc;
}
Widget paddingOwn(double val) {
return Padding(
padding: EdgeInsets.symmetric(
vertical: val,
horizontal: 180,
),
child: Text(
'My Life',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 30.0,
color: Colors.white70,
letterSpacing: 2.0),
),
);
}
@override
void dispose() {
animationControllerFade.dispose();
animationControllerPost.dispose();
super.dispose();
}
}
仍然没有结果。
如果要获取位置转换,需要使用SlideTransition
。
此外,您需要为 Tween
设置动画,以便正确插值。
我稍微更改了您的代码,以便将文本居中并从那里设置动画。无论如何,请记住 SlideTransition
适用于 Offsets in a relative way from the size of the child
现在,您应该能够根据您想要实现的最终结果调整此代码:
class _SplashScreenState extends State<SplashScreen> with TickerProviderStateMixin {
AnimationController _fadeAnimationController;
AnimationController _slideAnimationController;
double position = 400.0;
Animation<double> _fadeAnimation;
Animation<Offset> _slideAnimation;
@override
void initState() {
super.initState();
_fadeAnimationController = AnimationController(
vsync: this,
duration: Duration(milliseconds: 700),
);
_slideAnimationController = AnimationController(
vsync: this,
duration: Duration(milliseconds: 700),
);
_fadeAnimation = CurvedAnimation(
parent: _fadeAnimationController,
curve: Curves.easeIn,
);
_slideAnimation = Tween(begin: Offset(0, 0), end: Offset(0, -3)).animate(CurvedAnimation(
parent: _slideAnimationController,
curve: Curves.easeInOut,
));
_play();
}
Future<void> _play() async {
try {
await _fadeAnimationController.forward().orCancel;
await _slideAnimationController.forward().orCancel;
} on TickerCanceled {
//Handle if animation was canceled for whatever reason if you need it
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.amber,
body: Center(
child: SlideTransition(
position: _slideAnimation,
child: FadeTransition(
opacity: _fadeAnimation,
child: Text(
'My Life',
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30.0, color: Colors.white70, letterSpacing: 2.0),
),
),
),
),
);
}
@override
void dispose() {
_fadeAnimationController.dispose();
_slideAnimationController.dispose();
super.dispose();
}
}
更新:
您没有看到填充的变化,因为您有两个错误:
- 您没有为补间设置动画
- 您正在使用
symmetric
,从两侧添加相同的边距。
要解决补间问题,您需要添加如下内容:
tween = Tween(begin: 400, end: 200).animate(animationController);
要解决填充问题,您可以使用 only
,仅在一侧应用 填充:
padding: EdgeInsets.only(top: tween)