This article, translated from 👉Staggered Animations, is officially the last animation tutorial given. By the end of this tutorial, make your animations more homogeneous. You can make them larger while fading in. You can make the shape change as the size changes.
The content of this article
Interlacing animation can be an animation sequence that links back and forth, or an animation effect that overlaps
Creating interlaced animations requires the use of multiple Animation objects that have only one control
Each animation object needs to specify an Interval to indicate when the animation starts and ends in the entire animation sequence
Use Tween to create each animation
Interlacing is a straightforward concept: the animation effect on a page is a series of animations, rather than one animation at a time being added manually. An animation may be a pure series of animations that go back and forth. There may also be partial or complete overlap between animations. Or it could be blank animation, and nothing happens.
This article describes how to build staggered animation in Flutter.
case
This article uses basic interleaved cases, but for more complex cases see staggered_PIC_selection.
-
basic_staggered_animation
-
staggered_pic_selection
Here’s what we did:
The basic structure of interlacing animation
- All animations are made by the same
AnimationController
driven- Regardless of the duration of the animation, the value of controller must be in the closed range of 0-1.
- Every animation has a 0-1 closed interval
Interval
The value of the- Individual animations are called intervals, and one is created for each interval
Tween
,Tween
Specifies the startTween
The animation is created and is managed by the controller
The following illustration illustrates the use of Interval in the code sample, with the following points to note:
The opacity changes account for about 10% of the animation time
There is a small gap between transparency and width animation
There are no animations for the last 25% of the timeline
The Padding animation and the height change animation are completely superimposed, and the two animations happen together
Rounded corners were added to make the rectangle round
The spacing and height animations overlap because they have the same interval and will be staggered if they are different
Assemble animation:
-
Create an AnimationController to manage all animations
-
Create a Tween for each property you want to animate
-
Tween defines the range of animation effects such as transparency from 0 to 1 and color from green to white
-
Tween’s Animate method requires a parent animation, which is the AnimationController
-
-
Specify the curve property for the animation
Whenever the value of the animation changes, then the UI changes, and that’s the animation.
The following code creates a Tween of the width property and specifies the curve.
width = Tween<double>(
begin: 50.0,
end: 150.0,
).animate(
CurvedAnimation(
parent: controller,
curve: Interval(
0.125.0.250,
curve: Curves.ease,
),
),
),
Copy the code
The begin and end attributes do not have to be values of type double; the code below is borderRadius values.
borderRadius = BorderRadiusTween(
begin: BorderRadius.circular(4.0),
end: BorderRadius.circular(75.0),
).animate(
CurvedAnimation(
parent: controller,
curve: Interval(
0.375.0.500,
curve: Curves.ease,
),
),
),
Copy the code
Complete staggered animation
Like all interactive components, a complete animation consists of a pair of widgets: a StatelessWidget and a StatefulWidget
Specify the Tween in the StatelessWidget, define the Animation object, and build the Widget tree to animate in the Build () method.
StatefulWidget creates controllers, drives animations, and builds a non-animated Widget tree.
Full code for basic_staggered_animation’s main.dart
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart' show timeDilation;
class StaggerAnimation extends StatelessWidget {
StaggerAnimation({Key? key, required this.controller})
:
// Each animation defined here transforms its value during the subset
// of the controller's duration defined by the animation's interval.
// For example the opacity animation transforms its value during
// the first 10% of the controller's duration.
opacity = Tween<double>(
begin: 0.0,
end: 1.0,
).animate(
CurvedAnimation(
parent: controller,
curve: const Interval(
0.0.0.100,
curve: Curves.ease,
),
),
),
width = Tween<double>(
begin: 50.0,
end: 150.0,
).animate(
CurvedAnimation(
parent: controller,
curve: const Interval(
0.125.0.250,
curve: Curves.ease,
),
),
),
height = Tween<double>(begin: 50.0, end: 150.0).animate(
CurvedAnimation(
parent: controller,
curve: const Interval(
0.250.0.375,
curve: Curves.ease,
),
),
),
padding = EdgeInsetsTween(
begin: const EdgeInsets.only(bottom: 16.0),
end: const EdgeInsets.only(bottom: 75.0),
).animate(
CurvedAnimation(
parent: controller,
curve: const Interval(
0.250.0.375,
curve: Curves.ease,
),
),
),
borderRadius = BorderRadiusTween(
begin: BorderRadius.circular(4.0),
end: BorderRadius.circular(75.0),
).animate(
CurvedAnimation(
parent: controller,
curve: const Interval(
0.375.0.500,
curve: Curves.ease,
),
),
),
color = ColorTween(
begin: Colors.indigo[100],
end: Colors.orange[400],
).animate(
CurvedAnimation(
parent: controller,
curve: const Interval(
0.500.0.750,
curve: Curves.ease,
),
),
),
super(key: key);
final Animation<double> controller;
final Animation<double> opacity;
final Animation<double> width;
final Animation<double> height;
final Animation<EdgeInsets> padding;
finalAnimation<BorderRadius? > borderRadius;finalAnimation<Color? > color;// This function is called each time the controller "ticks" a new frame.
// When it runs, all of the animation's values will have been
// updated to reflect the controller's current value.
Widget _buildAnimation(BuildContext context, Widget? child) {
return Container(
padding: padding.value,
alignment: Alignment.bottomCenter,
child: Opacity(
opacity: opacity.value,
child: Container(
width: width.value,
height: height.value,
decoration: BoxDecoration(
color: color.value,
border: Border.all(
color: Colors.indigo[300]! , width:3.0,
),
borderRadius: borderRadius.value,
),
),
),
);
}
@override
Widget build(BuildContext context) {
returnAnimatedBuilder( builder: _buildAnimation, animation: controller, ); }}class StaggerDemo extends StatefulWidget {
const StaggerDemo({Key? key}) : super(key: key);
@override
_StaggerDemoState createState() => _StaggerDemoState();
}
class _StaggerDemoState extends State<StaggerDemo>
with TickerProviderStateMixin {
late AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(milliseconds: 2000), vsync: this);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
Future<void> _playAnimation() async {
try {
await _controller.forward().orCancel;
await _controller.reverse().orCancel;
} on TickerCanceled {
// the animation got canceled, probably because we were disposed}}@override
Widget build(BuildContext context) {
timeDilation = 10.0; // 1.0 is normal animation speed.
return Scaffold(
appBar: AppBar(
title: const Text('Staggered Animation'),
),
body: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
_playAnimation();
},
child: Center(
child: Container(
width: 300.0,
height: 300.0,
decoration: BoxDecoration(
color: Colors.black.withOpacity(0.1),
border: Border.all(
color: Colors.black.withOpacity(0.5), ), ), child: StaggerAnimation(controller: _controller.view), ), ), ), ); }}void main() {
runApp(
const MaterialApp(
home: StaggerDemo(),
),
);
}
Copy the code
StatelessWidget: StaggerAnimation
In the StaggerAnimation class above, the Build () method constructs the AnimatedBuilder, which builds the animation. AnimatedBuilder uses the values of Tweens to construct the Widget tree to be animated. In this example, the _buildAnimation() method is called and the result is the Builder property. AnimatedBuilder listens for notifications from the Controller, marking that the Widget tree needs to be rebuilt. _buildAnimation() is called for each tick that changes the animation value.
Statefulwidget: StaggerDemo
In the StaggerDemo above, we created the AnimationController, which manages all the animations and specifies the animation duration to be 2000 ms. The Controller drives the animation and builds the Widget tree that does not require the animation effect. An animation is triggered when the screen is clicked, and a reverse is performed when the animation is complete.
conclusion
At this point, the official animation documents are all translated, with concepts introduced, such as what is staggered animation, what is Hero animation. There are class documents, such as AnimatedBuilder, AnimationController, and so on. I’m going to string all of these together.
This article allows you to say a few words on the Flutter animation
After watching, you can tell others which class has implemented the Flutter animation
Learn animation with the Official Flutter tutorial
Unknowingly, Hero animation