Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.
preface
We introduced it in the last postAnimation
和 AnimationController
The use of this is the most basic animation builder class. However, if we want to build a reusable animation component that controls its animation effects through external parameters, the previous approach is not appropriate. Provided in FlutterAnimatedWidget
Component is used to build reusable animation components. We useAnimatedWidget
To achieve the 3D rotation effect of the component, as shown in the figure below.
AnimatedWidget profile
The AnimatedWidget is an abstract StatefulWidget with the constructor shown below.
const AnimatedWidget({
Key? key,
required this.listenable,
}) : assert(listenable ! =null),
super(key: key);
Copy the code
The main thing is to receive a ListEnable parameter, usually an Animation object. In the _AnimatedState class inside the AnimatedWidget, the object change listen callback is added to refresh the interface.
class _AnimatedState extends State<AnimatedWidget> {
@override
void initState() {
super.initState();
widget.listenable.addListener(_handleChange);
}
@override
void didUpdateWidget(AnimatedWidget oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.listenable != oldWidget.listenable) {
oldWidget.listenable.removeListener(_handleChange);
widget.listenable.addListener(_handleChange);
}
}
@override
void dispose() {
widget.listenable.removeListener(_handleChange);
super.dispose();
}
void _handleChange() {
setState(() {
// The listenable's state is our build state, and it changed already.
});
}
// ...
}
Copy the code
As you can see, once we just pass the Animation object to the AnimatedWidget object, we don’t need to do things like write addListener ourselves. And the whole animation can be given to the external control of other objects, so as to achieve the reuse of animation components.
3D rotation animation implementation
The implementation of 3D rotation is relatively simple. In the Container component, there are two parameters to control the transformation, respectively:
transform
:Matrix4
Object, you can achieve rotation, translation, and deformation around the X, Y, Z axis. aboutMatrix4
Involves a lot of matrix operations and linear algebra knowledge, you can refer to the source code Matrix4 review their own college mathematics knowledge 😂.transformAlignment
The alignment of the transformation, which can be understood as the starting position, can be usedAlignment
Object to set.
With this foundation, we can define 3D rotation effects. We define a generic component, ThreeDAnimatedWidget:
class ThreeDAnimatedWidget extends AnimatedWidget {
final Widget child;
const ThreeDAnimatedWidget(
{Key? key, required Animation<double> animation, required this.child})
: super(key: key, listenable: animation);
@override
Widget build(BuildContext context) {
final animation = listenable as Animation<double>;
returnCenter( child: Container( transform: Matrix4.identity() .. rotateY(2* pi * animation.value) .. setEntry(1.0.0.01), transformAlignment: Alignment.center, child: child, ), ); }}Copy the code
Here we have rotated the Y axis around the center point, and set the Angle of the tilt using setEntry (this will make it more three-dimensional). We can actually rotate around the X or Z axis as well. Next is the application of the animation component, we build a shaded text (looks like stereo word) as a child of the animation, the other controls are similar to the previous one, the complete code is as follows:
class AnimatedWidgetDemo extends StatefulWidget {
const AnimatedWidgetDemo({Key? key}) : super(key: key);
@override
_AnimatedWidgetDemoState createState() => _AnimatedWidgetDemoState();
}
class _AnimatedWidgetDemoState extends State<AnimatedWidgetDemo>
with SingleTickerProviderStateMixin {
late Animation<double> animation;
late AnimationController controller;
@override
void initState() {
super.initState();
controller =
AnimationController(duration: const Duration(seconds: 3), vsync: this);
animation = Tween<double>(begin: 0.0, end: 1.0).animate(controller);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('AnimatedWidget animation'),
),
body: ThreeDAnimatedWidget(
animation: animation,
child: Text(
'Island code farmer',
style: TextStyle(
fontSize: 42.0,
color: Colors.blue,
fontWeight: FontWeight.bold,
shadows: [
Shadow(
blurRadius: 2,
offset: Offset(2.0.1.0),
color: Colors.blue[900]!) , ], ), ), ), floatingActionButton: FloatingActionButton( child: Icon(Icons.play_arrow, color: Colors.white), onPressed: () {if (controller.status == AnimationStatus.completed) {
controller.reverse();
} else{ controller.forward(); }},),); }@override
void dispose() {
controller.dispose();
super.dispose(); }}Copy the code
As you can see, the ThreeDAnimatedWidget can be reused by passing in an Animation object and child components in a scenario that requires such Animation. For example, let’s change the text to a picture.
/ /...
body: ThreeDAnimatedWidget(
animation: animation,
child: Image.asset(
'images/avatar.jpg',
width: 100,
height: 100,),),/ /...
Copy the code
conclusion
This article introduces the use of an AnimatedWidget, which allows you to build reusable animation components. In addition, the transform property of the Container plus the AnimatedWidget implements 3d rotation. In the actual development process, we can build many personalized and reusable animation components based on the AnimatedWidget to make the application more interesting.
I am dao Code Farmer with the same name as my wechat official account. This is a column about the introduction and practice of Flutter, providing systematic learning articles about Flutter. See the corresponding source code here: The source code of Flutter Introduction and Practical column. If you have any questions, please add me to the wechat account: island-coder. If you feel you have something to gain, please give three pairs of love as follows:
👍🏻 : a praise to encourage!
🌟 : Collect articles, easy to look back!
💬 : Comment exchange, mutual progress!