Flutter FadeIn/FadeOut 动画一起
Posted
技术标签:
【中文标题】Flutter FadeIn/FadeOut 动画一起【英文标题】:Flutter FadeIn/FadeOut animation together 【发布时间】:2019-12-23 18:50:27 【问题描述】:在这个简单的示例代码中,我想同时使用fadeIn 和fadeOut 动画,但是在此代码中,fadeIn 只能工作而reverse
不能工作,我怎样才能将它们都放在一起?
import 'package:flutter/material.dart';
void main()=>runApp(MaterialApp(home: FadeTransitionSample(),));
class FadeTransitionSample extends StatefulWidget
@override
State<StatefulWidget> createState() => _Fade();
class _Fade extends State<FadeTransitionSample> with TickerProviderStateMixin
AnimationController animation;
Animation<double> _fadeInFadeOut;
@override
void initState()
super.initState();
animation = AnimationController(vsync: this, duration: Duration(seconds: 3),);
_fadeInFadeOut = Tween<double>(begin: 0.0, end: 0.1).animate(animation);
animation.addListener(()
if(animation.isCompleted)
animation.reverse();
else
animation.forward();
);
animation.repeat();
@override
Widget build(BuildContext context)
return Scaffold(
body: Container(
child: Center(
child: FadeTransition(
opacity: animation,
child: Container(
color: Colors.green,
width: 100,
height: 100,
),
),
),
),
);
【问题讨论】:
【参考方案1】:好的,我假设您希望在容器上获得 FadeIn 和 FadeOut 动画。
您需要更改一些内容。
FadeTransition
类不应将 animation
用于不透明度,而应使用 _fadeInFadeOut
变量
当您调用 animation.forward()
而不是 animation.repeat()
时,动画开始(因为在您的情况下,您还需要反转动画,请始终从 animation.forward() 调用开始)。
确保使用addStatusListener()
方法而不是addListener()
,因为您可以更好地控制您的状态。
所以,所有这些放在一起,下面是使您的动画工作的工作代码。
import 'package:flutter/material.dart';
void main()=>runApp(MaterialApp(home: FadeTransitionSample(),));
class FadeTransitionSample extends StatefulWidget
@override
State<StatefulWidget> createState() => _Fade();
class _Fade extends State<FadeTransitionSample> with TickerProviderStateMixin
AnimationController animation;
Animation<double> _fadeInFadeOut;
@override
void initState()
super.initState();
animation = AnimationController(vsync: this, duration: Duration(seconds: 3),);
_fadeInFadeOut = Tween<double>(begin: 0.0, end: 0.5).animate(animation);
animation.addStatusListener((status)
if(status == AnimationStatus.completed)
animation.reverse();
else if(status == AnimationStatus.dismissed)
animation.forward();
);
animation.forward();
@override
Widget build(BuildContext context)
return Scaffold(
body: Container(
child: Center(
child: FadeTransition(
opacity: _fadeInFadeOut,
child: Container(
color: Colors.green,
width: 100,
height: 100,
),
),
),
),
);
【讨论】:
谢谢。如何设置正向和反向之间的延迟? 目前,FadeIn 和 Fade Out 的延迟是相同的。如果您想为两个动作设置不同的持续时间,您必须创建单独的动画并使用它们。不能用简单的反向方法做到这一点。还有其他调用,如 animateTo() 和 animateBack() 您可以利用它们。【参考方案2】:为此,请使用 AnimatedOpacity
小部件。
注意:要打开/关闭可见性,opacity
是 true
或 false
。控制孩子淡入淡出过渡的动画。
AnimatedOpacity
小部件需要三个参数:
opacity
:从 0.0(不可见)到 1.0(完全可见)的值。
duration
: 动画需要多长时间才能完成。
child
:动画小部件。在这种情况下,绿色框。
这是代码文件:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget
const MyApp(Key? key) : super(key: key);
@override
Widget build(BuildContext context)
const appTitle = 'Opacity Demo';
return const MaterialApp(
title: appTitle,
home: MyHomePage(title: appTitle),
);
// The StatefulWidget's job is to take data and create a State class.
// In this case, the widget takes a title, and creates a _MyHomePageState.
class MyHomePage extends StatefulWidget
const MyHomePage(
Key? key,
required this.title,
) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
// The State class is responsible for two things: holding some data you can
// update and building the UI using that data.
class _MyHomePageState extends State<MyHomePage>
// Whether the green box should be visible
bool _visible = true;
@override
Widget build(BuildContext context)
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: AnimatedOpacity(
// If the widget is visible, animate to 0.0 (invisible).
// If the widget is hidden, animate to 1.0 (fully visible).
opacity: _visible ? 1.0 : 0.0,
duration: const Duration(milliseconds: 500),
// The green box must be a child of the AnimatedOpacity widget.
child: Container(
width: 200.0,
height: 200.0,
color: Colors.red,
),
),
),
);
【讨论】:
【参考方案3】:简单的解决方案,直接用更少的代码,想法是在FadeIn
中组合FadeOut
并给FadeOut
延迟量大于FadeIn
的持续时间,只需复制和粘贴然后只需更改Image.asset
小部件到您想要淡入/淡出的任何内容
FadeIn(
animate: true,
duration: Duration(seconds: 2),
child: FadeOut(
animate: true,
delay: Duration(seconds: 2),
duration: Duration(seconds: 1),
// Just change the Image.asset widget to anything you want to fade in/out:
child: Image.asset(
"assets/images/logo.png",
height: 150,
width: 150,
fit: BoxFit.contain,
), //Image.asset
) // FadeOut
), // FadeIn
【讨论】:
以上是关于Flutter FadeIn/FadeOut 动画一起的主要内容,如果未能解决你的问题,请参考以下文章
transitionend事件 监听 fadeIn fadeOut 两个方法无效(动画结束时无法执行transitionend里面的代码)
jQuery - fadeIn()、fadeOut()、animate()、stop() 和闪烁
210 jQuery淡入淡出:fadeIn() fadeOut() fadeToggle() fadeTo()