What is animation
Animation is a series of static images changing continuously at a certain frequency, resulting in visual retention of the naked eye.
Why we need animation
Whether it is mobile terminal or Web terminal development, when there is a scene of interaction with the user, the introduction of animation can make the application experience smoother, user experience better, and enhance the availability and interest of the product. Creating animations in Flutter can be implemented in many different ways, making it easy to implement various animation types. Animation in Flutter can be understood as the process by which a Widget changes from one state (size, position, color, transparency, font, etc.) to another state over a period of time.
How to select animation for Flutter development
From I Want a Flutter Animation! Starting, we end up with four ends that guide our choice of animation implementation, with increasing complexity from top to bottom.
- Implicit Animations
- Explicit Animations
- Low-Level Animations
- Third-Party Animation Framework
Basic concept
Animation
Saves the current state of the animation (for example, whether to start, pause, go forward or go backwards).
abstract class Animation<T> extends Listenable implements ValueListenable<T> {
/// Abstract const constructor. This constructor enables subclasses to provide
/// const constructors so that they can be used in const expressions.
const Animation();
///.
/// The current status of this animation.
AnimationStatus get status;
/// The current value of the animation.
@override
T get value;
Copy the code
AnimationController
Manage Animation, control the start and end of Animation, etc
class AnimationController extends Animation<double>
with AnimationEagerListenerMixin.AnimationLocalListenersMixin.AnimationLocalStatusListenersMixin {
///.
}
Copy the code
Curve
It can be understood as a curve of two values, such as uniform speed, first acceleration then deceleration, deceleration and so on
abstract class Curve extends ParametricCurve<double> {
/// Abstract const constructor to enable subclasses to provide
/// const constructors so that they can be used in const expressions.
const Curve();
///.
}
Copy the code
A Flutter has several types of curves built into it.
Curve Demonstrate various effects
Tween
Sets the range value for the animation object.
class Tween<T extends dynamic> extends Animatable<T> {
/// Creates a tween.
///
/// The [begin] and [end] properties must be non-null before the tween is
/// first used, but the arguments can be null if the values are going to be
/// filled in later.
Tween({
this.begin,
this.end,
});
}
Copy the code
Ticker
Callbacks used to register screen refreshes to drive animation execution.
An implicit animation
The simplest Animation, implicit Animation, is usually inherited from the ImplicitlyAnimatedWidget. Implicit Animation is called because Flutter hides some details when used. We don’t need to worry about the creation of Animation and AnimationController. Just pay attention to what state the Widget goes from. Of course, implicit Animation is not without Animation and AnimationController, but the superclass ImplicitlyAnimatedWidget that Flutter creates for us, The main code for ImplicitlyAnimatedWidget is as follows:
abstract class ImplicitlyAnimatedWidget extends StatefulWidget {
const ImplicitlyAnimatedWidget({
Key key,
this.curve = Curves.linear,
@required this.duration,
this.onEnd,
}) : assert(curve ! =null),
assert(duration ! =null),
super(key: key);
final Curve curve;
final Duration duration;
final VoidCallback onEnd;
@override
ImplicitlyAnimatedWidgetState<ImplicitlyAnimatedWidget> createState();
}
abstract class ImplicitlyAnimatedWidgetState<T extends ImplicitlyAnimatedWidget> extends State<T> with SingleTickerProviderStateMixin<T> {
@protected
AnimationController get controller => _controller;
AnimationController _controller;
/// The animation driving this widget's implicit animations.
Animation<double> get animation => _animation;
Animation<double> _animation;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: widget.duration,
debugLabel: kDebugMode ? widget.toStringShort() : null,
vsync: this,); _controller.addStatusListener((AnimationStatus status) {switch (status) {
case AnimationStatus.completed:
if(widget.onEnd ! =null)
widget.onEnd();
break;
case AnimationStatus.dismissed:
case AnimationStatus.forward:
case AnimationStatus.reverse:
}
});
_updateCurve();
_constructTweens();
didUpdateTweens();
}
///.
}
Copy the code
Commonly used implicit animations are
- AnimatedContainer
- AnimatedAlign
- AnimatedCrossFade
- AnimatedDefaultTextStyle
- AnimatedOpacity
- AnimatedPadding
- AnimatedPhysicalModel
- AnimatedPositioned
- AnimatedSize
- AnimatedSwitcher
- AnimatedTheme
AnimatedContainer
For example, adding an animation to a Container:
InkWell( onTap: () { setState(() { selected = ! selected; }); }, child: AnimatedContainer( color: Colors.blue, curve: _curve, margin:const EdgeInsets.all(20),
duration: Duration(seconds: 1),
width: selected ? 200.0 : 100.0,
height: selected ? 100.0 : 200.0,),),Copy the code
Explicit animation
Explicit Animation is a little more complicated than implicit Animation, requiring us to specify the Animation and AnimationController. Explicit animations generally inherit from the AnimatedWidget.
Common explicit animations are
- AlignTransition
- ScaleTransition
- SizeTransition
- SlideTransition
- PositionedTransition
- RelativePositionedTransition
class _SizeTransitionDemoState extends State<SizeTransitionDemo>
with TickerProviderStateMixin {
AnimationController _controller;
Animation<double> _animation;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 3),
vsync: this,);/ /.. repeat();
_animation = CurvedAnimation(
parent: _controller,
curve: Curves.fastOutSlowIn,
);
_controller.repeat();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("SizeTransition"),
actions: [
IconButton(icon: Icon(Icons.settings), onPressed: () {}),
],
),
body: SingleChildScrollView(
child: Column(
children: [
SizeTransition(
sizeFactor: _animation,
axis: Axis.horizontal,
// axisAlignment: -1,
child: Center(
child: FlutterLogo(size: 200.0(() [() [() [() [() [() [() }}Copy the code
Custom CustomPainter
CustomPainter can be understood as an advanced use of display animation, with custom brushes for finer control of animation.
class LinePainter extends CustomPainter {
final double progress;
LinePainter(this.progress);
@override
void paint(Canvas canvas, Size size) {
varpaint = Paint() .. color = Colors.yellowAccent .. strokeWidth =5
..strokeCap = StrokeCap.round;
Offset startingPoint = Offset(0, size.height / 2);
Offset endingPoint = Offset(progress, size.height / 2);
canvas.drawLine(startingPoint, endingPoint, paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true; }}Copy the code
Lottie
Perform complex animations designed by designers in Lottie, typically in JSON format.
Lottie.network("https://assets7.lottiefiles.com/packages/lf20_wXxy5o.json", width: 300, height: 300),
Lottie.network("https://assets3.lottiefiles.com/packages/lf20_r9lh4ebq.json", width: 300, height: 300),
Lottie.asset('assets/64586-like-and-dislike-button.json'),
Lottie.asset('assets/65014-dog-walking.json'),
Lottie.asset('assets/65077-breathing-lotus.json'),
Copy the code
Visual retention demonstration
lottie files