The official documentation
Necessary concepts and classes
Animation
Object, it isFlutter
A core class in the animation library that inserts values used to guide the animationAnimation
The object knows the state of the current animation (whether the animation starts, stops, advances, or retreats), but nothing about what is displayed on the screenAnimationController
Object managementAnimation
CurvedAnimation
Define an animation as an animation of nonlinear motionTween
Interpolate between data ranges used by the animated object. For example,Tween
Interpolation may be defined from red to blue or from 0 to 255- use
Listeners
和StatusListeners
To listen for changes in animation state
steps
-
Initialize an AnimationController object
AnimationController controller = AnimationController(duration: const Duration(milliseconds: 500), vsync: this); Copy the code
-
Initialize an Animation object and pass in the AnimationController as a parameter. The Animation object here is created through the Animate method of the Tween object
Animation<int> alpha = IntTween(begin: 0, end: 255).animate(controller); Copy the code
-
Call the AnimationController’s forward() method to perform the animation
controller.forward(); Copy the code
-
Call the dispose() method on the Widget to release the resource
controller.dispose(); Copy the code
case
The following example changes the width and height of the widget in a given amount of time
- We need real-time access
Animation
的value
To assignwidgetThe wide high - To change thewidgetWidth and height, then need
setState(...)
To make thewidgetredraw
First we need a state-changing widget that inherits from the StatefulWidget, and then follow the steps we’ve done above with the following code:
class AnimateApp extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return_AnimateAppState(); }}class _AnimateAppState extends State<AnimateApp> with SingleTickerProviderStateMixin {
AnimationController controller;
Animation<double> animation;
@override
void initState() {
super.initState();
// Create the AnimationController object
controller = AnimationController(
vsync: this, duration: const Duration(milliseconds: 2000));
// Create an Animation using the Tween object
animation = Tween(begin: 50.0, end: 200.0).animate(controller) .. addListener(() {// Note: Do not omit this sentence, otherwise the widget will not be redrawn and the animation will not be visible
setState(() {});
})
// Perform the animation
controller.forward();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'AnimateApp',
theme: ThemeData(
primaryColor: Colors.redAccent
),
home: Scaffold(
appBar: AppBar(
title: Text('AnimateApp'),
),
body: Center(
child: Container(
// Gets the width and height assigned to the widget by the animation value
width: animation.value,
height: animation.value,
decoration: BoxDecoration(
color: Colors.redAccent
),
),
)
)
);
}
@override
void dispose() {
// Resource release
controller.dispose();
super.dispose(); }}Copy the code
The effect is as follows:
It can be seen that the above animation moves linearly. We can use CurvedAnimation to realize the animation code of nonlinear motion as follows:
controller = AnimationController(
vsync: this, duration: const Duration(milliseconds: 2000));
// Nonlinear animation
final CurvedAnimation curve = CurvedAnimation(
parent: controller, curve: Curves.elasticOut);
animation = Tween(begin: 50.0, end: 200.0).animate(curve) .. addListener(() { setState(() {}); });Copy the code
The effect is as follows:
We can then add a state listener to the Animation by adding addStatusListener(…) to the Animation. To monitor the state of the current animation, such as whether the animation is finished. We can add a state listener to the above example to let the animation execute indefinitely:
animation = Tween(begin: 50.0, end: 200.0).animate(curve) .. addListener(() { setState(() {}); }).. addStatusListener((status) {if (status == AnimationStatus.completed) {
controller.reverse();
} else if(status == AnimationStatus.dismissed) { controller.forward(); }});Copy the code
AnimationStatus.com pleted said animation at the end to stop state, this time we let the animation it reverses after (from); AnimationStatus. Dismissed said animation stops at the start, this time we let the animation normal execution (once upon a time in the future). This allows the animation to execute indefinitely.
Tween can also accept the Color parameter to change the Color of the widget from red to blue. The following code is used to change the Color of the widget from red to blue:
controller = AnimationController(
duration: const Duration(milliseconds: 3000), vsync: this); animation = ColorTween(begin: Colors.redAccent, end: Colors.blue).animate( controller) .. addListener(() { setState(() {}); }); controller.forward(); . child: Container( decoration: BoxDecoration( color: animation.value ), margin: EdgeInsets.symmetric(vertical:10.0),
height: 200.0,
width: 200.0,),Copy the code
The effect is as follows:
tip
with
We can see _AnimateAppState class followed a with SingleTickerProviderStateMixin, what do you mean this with? With is a key word in Dart. It can be interpreted as a mixin. Check out this answer on StackOverflow.
Mixin refers to the ability to add functionality from one or more classes to one’s own classes without having to inherit from those classes. You can call methods in these classes if you mix them. Dart does not have multiple inheritance, and you can use mixins to avoid the problems multiple inheritance can cause.
The _AnimateAppState class inherits the State class, but initializes the AnimationController with a TickerProvider vsync parameter. So we mixed with TickerProvider SingleTickerProviderStateMixin subclass
Look at a simple little example of mixing
void main() {
var a = new A();
a.methodB();
a.methodC();
a.methodD();
new E(a);
}
class A extends B with C.D {}class B {
void methodB() {
print('Class B methodB is call'); }}class C {
void methodC() {
print('Class C methodC is call'); }}class D {
void methodD() {
print('Class D methodD is call'); }}class E {
final C c;
E(this.c) { c.methodC(); }}Copy the code
You can see that class A inherits from class B, and then mixes with classes C and D. Then, in the main method, you can use instances of class A to call methods from classes B, C, and D. Then there is class E, which needs A class C as A parameter in the constructor, and since class A is mixed with class C, you can pass an instance of class A as A parameter into the constructor of class E.
Run the following output:
Class B methodB is call
Class C methodC is call
Class D methodD is call
Class C methodC is call
Copy the code
..addListener
In the example above, we see this notation
animation = Tween(begin: 50.0, end: 200.0).animate(curve) .. addListener(() { setState(() {}); });Copy the code
Notice the two dots before addListener.. Right? What does that mean? Let’s just look at a quick example!
void main() {
List<String> list = getList() .. add("android")
..add("flutter")
..add("kotlin")
..removeAt(0);
list.forEach((item) {
print(item);
});
// ---------- is equivalent to
print('-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --');
List<String> list2 = getList();
list2.add("android");
list2.add("flutter");
list2.add("kotlin");
list2.removeAt(0);
list2.forEach((item) {
print(item);
});
}
List<String> getList() {
return new List(a); }Copy the code
Enter the following:
flutter
kotlin
---------------------------
flutter
kotlin
Copy the code
If there are any mistakes, please also point out, thank you!