animation library:
要使用这个API请导入软件包:flutter/animation.dart。这个库提供了在Flutter中实现动画的基本构建块。框架的其他层使用这些构建块为应用程序提供高级动画支持。当我们寻找到的动画小组件不满足要求则可以使用此库提供的基本构建块实现自定义动画效果。
这个库仅仅依赖core Dart 库和 physics.dart 库.
这个库的基础是 Flutter将动画表示为在给定持续时间内发生变化的值,该值可以是任何类型。例如,它可以是一个double,表示Widget淡出时的当前不透明度。或者,它可以是从一种颜色平滑过渡到另一种颜色的小部件的当前背景颜色。动画的当前值由动画对象表示,该对象是动画库的中心类。除当前动画值外,动画对象还存储当前的AnimationStatus。状态指示动画当前是从开始到结束,还是从另一个角度运行。它还可能指示动画当前在开始或结束时停止。其他对象可以在动画上对象上注册监听器,以便在动画值或动画状态发生更改时收到通知。Widget可以通过Animation注册这样的值监听器。addListener以使用当前动画值重建自身且无论该值何时更改,监听器都会正常返回。例如,小部件可能会侦听动画,以便在每次值更改时将其不透明度更新为动画的值。同样,我们可以通过对动画注册状态监听器对于在当前动画结束时触发addStatusListener来启动另一个操作可能很有用。同时虽然我们不能直接实例化Animation(它是一个抽象类),但可以使用AnimationController创建一个实例对象进行你想进行的操作。
我们可以通过AnimationController完成Powering animations
AnimationController是一种特殊类型的动画,每当运行应用程序的设备准备好显示新的一帧时,它都会提升其动画值(通常,该速率约为每秒60个值)。AnimationController可以在需要使用动画的地方使用。顾名思义,AnimationController还提供对其Animation的控制:它实现了在任何时候停止动画并向前和向后运行动画的方法。
默认情况下,当向前运行时,AnimationController会在给定的持续时间内将其动画值从0.0线性增加到1.0。对于许多用例,您可能希望值具有不同的类型,更改动画值的范围,或更改动画在值之间移动的方式。这是通过包装动画实现的:在Animatable中包装动画(请参见下文)会将动画值的范围更改为不同的范围或类型(例如,为颜色或矩形设置动画)。此外,通过将曲线包裹在CurvedAnimation中,可以将曲线应用于动画。曲线动画不是线性增加动画值,而是根据提供的曲线更改其值。框架附带许多内置曲线(请参见曲线)。例如,曲线。easeOutCubic在动画开始时快速增加动画值,然后减慢速度,直到达到目标值。
我们可以通过 Animatable来设置不同类型的动画
Animatable<T>是以Animation<double>作为输入并生成T类型值的对象。这些类型的对象可用于将AnimationController(或任何其他类型double的Animation)的动画值范围转换为不同的范围。新的范围甚至不必再是双倍类型。在诸如Tween或TweenSequence之类的Animatable的帮助下,我们使用AnimationController可以用于在给定的持续时间内将颜色、矩形、大小和许多其他属性从一个值平滑的过渡到另一个值。这有助于我们更加灵活的操作我们的动画。
Tweens 对动画的插入值
Tween将应用于double类型的动画,以更改动画值的范围和类型。例如,要在两种颜色之间平滑过渡Widget的背景,可以使用ColorTween。每个Tween指定一个开始值和一个结束值。当为Tween提供动力的动画的动画值从0.0前进到1.0时,它会在其开始值和结束值之间生成插入值。当增强动画的动画值接近1.0时,Tween生成的值通常会越来越接近其最终值。Animation或AnimationController可以支持多个Tweens。例如,要并行设置小部件的大小和颜色的动画,请创建一个为SizeTween和ColorTween提供动力的AnimationController。
import 'package:flutter/material.dart';
class AnimatedExample extends StatefulWidget {
@override
_AnimatedExampleState createState() => _AnimatedExampleState();
}
class _AnimatedExampleState extends State<AnimatedExample>
with SingleTickerProviderStateMixin {
AnimationController _animationController;
Animation<double> _animation;
@override
void initState() {
super.initState();
// 创建动画控制器
_animationController = AnimationController(
duration: Duration(seconds: 2),
vsync: this,
);
// 创建动画
_animation = Tween<double>(begin: 0, end: 1).animate(_animationController);
// 启动动画
_animationController.forward();
}
@override
void dispose() {
// 销毁动画控制器
_animationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Animated Example'),
),
body: Center(
child: AnimatedBuilder(
animation: _animation,
builder: (BuildContext context, Widget? child) {
return Opacity(
opacity: _animation.value,
child: Container(
width: 200,
height: 200,
color: Colors.blue,
),
);
},
),
),
);
}
}
void main() {
runApp(MaterialApp(
home: AnimatedExample(),
));
}
在这个例子中,我们创建了一个简单的动画效果,当应用启动时,一个蓝色的容器将渐变地从透明度为0的状态过渡到透明度为1的状态。这是通过使用AnimationController
和Tween
来实现的。
我们在initState
方法中创建了一个动画控制器_animationController
,设置了动画的持续时间为2秒,并通过Tween
创建了一个从0到1的动画。
然后,在build
方法中,我们使用AnimatedBuilder
来监听动画的值变化,并在builder
函数中根据动画的值创建一个带有不透明度变化的容器。
最后,我们在main
函数中运行这个示例,并将AnimatedExample
作为主页的内容。
当然,我们可以通过TweenSequences设置交错动画
TweenSequence可以帮助我们在各个时期平滑地显示给定属性的动画。序列中的每个Tween负责不同的阶段,并具有相关权重。当动画运行时,阶段会一个接一个地执行。
import 'package:flutter/material.dart';
class StaggeredAnimationExample extends StatefulWidget {
@override
_StaggeredAnimationExampleState createState() =>
_StaggeredAnimationExampleState();
}
class _StaggeredAnimationExampleState extends State<StaggeredAnimationExample>
with SingleTickerProviderStateMixin {
AnimationController _animationController;
Animation<double> _animation;
@override
void initState() {
super.initState();
// 创建动画控制器
_animationController = AnimationController(
duration: Duration(seconds: 2),
vsync: this,
);
// 创建动画序列
final tweenSequence = TweenSequence<double>([
TweenSequenceItem<double>(
tween: Tween<double>(begin: 0, end: 1),
weight: 0.5, // 第一个动画占总时间的50%
),
TweenSequenceItem<double>(
tween: Tween<double>(begin: 1, end: 0),
weight: 0.5, // 第二个动画占总时间的50%
),
]);
// 应用动画序列
_animation = _animationController.drive(tweenSequence);
// 启动动画
_animationController.forward();
}
@override
void dispose() {
// 销毁动画控制器
_animationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Staggered Animation Example'),
),
body: Center(
child: AnimatedBuilder(
animation: _animation,
builder: (BuildContext context, Widget? child) {
return Opacity(
opacity: _animation.value,
child: Container(
width: 200,
height: 200,
color: Colors.blue,
),
);
},
),
),
);
}
}
void main() {
runApp(MaterialApp(
home: StaggeredAnimationExample(),
));
}
在这个例子中,我们使用TweenSequence
来创建一个交错动画效果。在动画序列中,我们定义了两个动画阶段:第一个阶段从透明度为0到1,占总时间的50%;第二个阶段从透明度为1到0,同样占总时间的50%。
在initState
方法中,我们创建了动画控制器_animationController
和动画序列tweenSequence
。然后,我们将动画序列应用到动画变量_animation
中,并在_animationController
上调用forward
方法来启动动画。
在build
方法中,我们使用AnimatedBuilder
来监听动画的值变化,并在builder
函数中根据动画的值创建一个带有不透明度变化的容器。
最后,我们在main
函数中运行这个示例,并将StaggeredAnimationExample
作为主页的内容。