如果正确使用动画,则可以极大地改变用户对您应用的看法。 与没有动画的应用程序相比,拥有许多快速,细腻的动画的应用程序看起来更精致,更专业。 在人满为患的市场Google Play上,这可能意味着成功与失败之间的区别。
Flutter也许是当今唯一可用的混合应用程序开发框架,它允许您创建可以每秒60帧连续运行的复杂动画。 在本教程中,我将帮助您了解Flutter小部件动画的基础知识。 我还将向您介绍一些可以简化动画代码的新小部件。
1.准备动画小部件
Flutter框架希望您遵循实用的反应式编程方法。 因此,要使小部件具有动画效果,您必须能够以适当的时间间隔重复更新其状态。
要创建易于制作动画的小部件,请先创建一个扩展StatefulWidget类的类并覆盖其createState()方法。 在方法内部,请确保您返回一个State实例。
class MyApp extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new MyState();
}
}为了具有动画效果,与有状态窗口小部件关联的状态对象不仅必须扩展State类,还必须使用一个称为SingleTickerProviderStateMixin的混合SingleTickerProviderStateMixin 。 顾名思义,mixin提供了一个Ticker对象,该对象反复生成回调,通常称为壁虱。 由于刻度是在均匀的时间间隔内反复生成的,因此您可以使用它们来决定何时渲染动画的各个帧。
class MyState extends State<MyApp>
with SingleTickerProviderStateMixin {
@override
Widget build(BuildContext context) {
// More code here
}
}2.创建补间动画
补间动画是可以使用Flutter创建的最简单的动画之一。 创建它时,您要做的就是提供两个不同的值:一个开始值和一个结束值。 然后,框架将自动生成一组中间值(或中间值),这些中间值从起始值开始并平滑增长以匹配结束值。 通过逐渐将这些中间值应用于窗口小部件的属性,可以对该属性进行动画处理。
现在,让我们创建一个简单的补间动画,该控件将小部件从屏幕的左上角移动到屏幕的右上角。 换句话说,让我们为小部件的left属性设置动画。
要创建和控制动画,您将需要一个Animation对象和一个AnimationController对象。 将它们添加为您所在州的成员变量:
Animation<double> animation;
AnimationController controller;您必须通过重写类的initState()方法来初始化两个对象。 在方法内部,调用AnimationController类的构造函数以初始化控制器。 它期望将TickerProvider对象作为其输入之一。 因为国家已经使用了SingleTickerProviderStateMixin混入,你可以通过this给它。 此外,您可以使用duration属性来指定动画的持续时间。
以下代码创建一个持续时间为四秒的动画控制器:
@override
void initState() {
super.initState();
controller = new AnimationController(vsync: this,
duration: new Duration(seconds: 4));
// More code here
}此时,您可以创建一个Tween对象,指定动画的开始值和结束值。
Tween tween = new Tween<double>(begin: 10.0, end: 180.0);要将Tween对象与AnimationController对象相关联,必须调用其animate()方法。 该方法的返回值是一个Animation对象,您可以将其存储在类的第二个成员变量中。
animation = tween.animate(controller);Animation对象为代码的每个滴答生成一个动画事件,您必须处理该事件才能使动画起作用。 为此,可以使用其addListener()方法。 此外,在事件处理程序内部,必须调用setState()方法来更新小部件的状态并重新绘制它。 以下代码向您展示了如何:
animation.addListener(() {
setState(() {
});
});请注意,除非有其他要更新的状态变量,否则不必在setState()方法内编写任何代码。
最后,要启动动画,必须调用动画控制器的forward()方法。
controller.forward();动画已准备就绪。 但是,您仍未将其应用于屏幕上绘制的任何小部件。 现在,我建议您将其应用于包含“材质Icon小部件的“ Positioned小部件。 为此,在创建窗口小部件时,只需将其left属性的value设置为Animation对象的value属性。
因此,将以下代码(覆盖了build()方法)添加到状态:
@override
Widget build(BuildContext context) {
return new Container(
color: Colors.white,
child: new Stack(
children: <Widget>[
new Positioned(
child: new Material(
child: new Icon(Icons.airport_shuttle,
textDirection: TextDirection.ltr,
size: 81.0
)
),
left: animation.value, // Animated value
top: 30.0 // Fixed value
)
],
textDirection: TextDirection.ltr,)
);
}请注意,在上面的小部件树中有一个Stack小部件,因为Positioned小部件必须始终嵌入其中。
您现在可以运行您的应用以查看动画。
3.处理动画状态事件
如果要在动画结束时收到通知,可以将AnimationStatusListener对象附加到Animation对象。 在侦听器内部,如果当前动画状态已completed或被dismissed ,则可以确保动画已结束。
Flutter中的补间动画是可逆的。 这就是为什么有两个不同的状态常量表示动画结束的原因。 如果当前状态为completed ,则表示动画已在补间的结束值处结束。 如果将其dismissed ,则表示动画已以起始值结束。 使用这两种状态以及forward()和reverse()方法,您可以轻松地在动画之间来回创建。
您可以将以下代码添加到initState()方法中,向您展示如何反转和重复在上一步中创建的动画:
animation.addStatusListener((status) {
if(status == AnimationStatus.completed)
controller.reverse();
else if(status == AnimationStatus.dismissed)
controller.forward();
});如果再次运行该应用程序,您将看到动画不断重复。
4.使用动画小部件
Flutter框架提供了一些易于制作动画的小部件,您可以使用这些小部件使动画代码的冗长程度略微降低,但可重用性更高。 它们都是AnimatedWidget类的子类,并且期望在其构造函数中使用Animation或AnimationController对象。
最常用的动画小部件之一是RotationTransition小部件。 它允许您快速将旋转动画应用于其子级。 要使用它,首先创建一个新的动画控制器。 以下代码创建一个持续时间设置为六秒的代码:
controller = new AnimationController(vsync: this,
duration: new Duration(seconds: 6));要这次启动动画,请使用repeat()方法,而不是forward() repeat()方法。 这样可以确保动画不断重复。
controller.repeat();为了简单起见,可以将“ Text窗口小部件用作RotationTransition小部件的子级。 因此,相应地创建一个小部件树。 但是,在创建RotationTransition小部件时,请确保将其turns属性的值设置为刚创建的AnimationController对象。 (可选)您可以将两个小部件都放置在Center小部件内。 这是如何做:
@override
Widget build(BuildContext context) {
return new Center(
child: new RotationTransition(
turns: controller,
child: new Text("\u{1F43A}",
textDirection: TextDirection.ltr,
style: new TextStyle(fontSize: 85.0),)
)
);
}在上面的代码中,我使用了Unicode表情符号代码点作为Text小部件的内容。 之所以允许这样做,是因为Flutter开箱即用地支持表情符号。
再次运行该应用程序时,您应该在屏幕上看到以下内容:
ScaleTransition小部件与RotationTransition小部件非常相似。 您可能已经猜到了,它可以为子级的动画设置动画。 创建它时,您需要做的就是将AnimationController对象传递给它的scale属性。 以下代码向您展示了您如何:
@override
Widget build(BuildContext context) {
return new Center(
child: new ScaleTransition(
scale: controller,
child: new Text("\u{1F43A}",
textDirection: TextDirection.ltr,
style: new TextStyle(fontSize: 85.0),)
)
);
}现在,您将可以在动画过程中查看“ Text小部件的比例更改。
如果您想知道为什么我们没有为上述动画创建任何Tween对象,那是因为默认情况下, AnimationController类使用0.0和1.0作为begin值和end值。
5.使用曲线
我们在前面的步骤中创建的所有动画均遵循线性曲线。 结果,它们看起来不太现实。 通过更改Tween对象生成中间值的方式,可以更改它。
Flutter有一个名为CurvedAnimation的类,该类使您可以将非线性曲线应用于补间。 与Curves类一起使用时,该类提供了各种曲线,例如easeIn和easeOut ,您可以创建更自然的动画。
要创建CurvedAnimation对象,您需要一个AnimationController对象作为父对象。 您可以自由使用您在前面的步骤中创建的控制器之一,也可以创建一个新的控制器。 以下代码创建一个新控制器,其持续时间设置为五秒,以及一个CurvedAnimation对象,其curve属性设置为bounceOut曲线:
controller = new AnimationController(
vsync: this,
duration: new Duration(seconds: 5)
);
CurvedAnimation curvedAnimation = new CurvedAnimation(
parent: controller,
curve: Curves.bounceOut
);现在,您可以创建一个Tween对象,并通过调用其animate()方法将CurvedAnimation对象应用于该对象。 动画准备好后,别忘了向动画添加侦听器,更新状态,然后调用forward()方法启动它。
Tween myTween = new Tween<double>(begin: 150.0, end: 450.0);
animation = myTween.animate(curvedAnimation);
animation.addListener(() {
setState(() {
});
});
controller.forward();要查看动画,让我们将其应用于“ Positioned小部件的top属性。 您可以在其中随意添加任何子窗口小部件。 在以下代码中,我添加了一个显示另一个表情符号的Text小部件。
@override
Widget build(BuildContext context) {
return new Stack(
children: [
new Positioned(
child: new Text("\u{26BE}",
textDirection: TextDirection.ltr,
style: new TextStyle(
fontSize: 70.0
)
),
left: 50.0,
top: animation.value // Animated property
)
],
textDirection: TextDirection.ltr,
);
}热重启后,您的应用现在应显示以下动画:
结论
您现在知道了使用Flutter框架创建补间动画的基础。 在本教程中,您还学习了如何使用曲线使它们看起来更自然。 一定要了解,在慢速模式(这是开发过程中的默认模式)下,动画可能看起来有些滞后且不稳定。 只有在发布模式下,您才能看到它们的真实性能。
要了解更多信息,请参阅官方文档 。
翻译自: https://code.tutsplus.com/tutorials/google-flutter-from-scratch-animating-widgets--cms-31709