Flutter AnimatedContainer 隐式动画渐变
一、AnimatedContainer
Flutter 中实现动画的方式有很多,AnimatedContainer
是实现渐变动画的一种方式,Flutter 中称为 隐式动画
实际上 AnimatedContainer 的行为表现,更像是一种渐变过程,它会对新旧属性的值变化之间生成动画效果
AnimatedContainer 的使用上,一般需要配合 StatefulWidget 来保存不同的 state 状态
1、创建默认属性的 StatefulWidget
double _opacity = 1.0;
Matrix4 _transform = Matrix4.translationValues(0, 0, 0);
上面设置了两个 state ,分别是透明值和位置变换,位置变换需要使用 matrix 类型进行计算
2、 AnimatedContainer Widget
AnimatedContainer 的构造如下,其中 duration
是 required 的,其他都是一些属性,比如 margin/transform/width/height/color/
AnimatedContainer 会在 state 变化的时候,去进行一些区间动画
AnimatedContainer({
Key key,
this.alignment,
this.padding,
Color color,
Decoration decoration,
this.foregroundDecoration,
double width,
double height,
BoxConstraints constraints,
this.margin,
this.transform,
this.child,
Curve curve = Curves.linear,
@required Duration duration,
Duration reverseDuration,
})
AnimatedContainer 对 state 更新是借助 ImplicitlyAnimatedWidgetState
生命周期的控制中实现的,其中在 didUpdatedWidget
的时候,会去依次遍历目标 value,如果需要进行渐变,则会依赖 Curve.transform
做动画。
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: widget.duration,
reverseDuration: widget.reverseDuration,
debugLabel: kDebugMode ? '${widget.toStringShort()}' : null,
vsync: this,
);
_updateCurve();
_constructTweens();
didUpdateTweens();
}
@override
void didUpdateWidget(T oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.curve != oldWidget.curve)
_updateCurve();
_controller.duration = widget.duration;
_controller.reverseDuration = widget.reverseDuration;
if (_constructTweens()) {
forEachTween((Tween<dynamic> tween, dynamic targetValue, TweenConstructor<dynamic> constructor) {
_updateTween(tween, targetValue);
return tween;
});
_controller
..value = 0.0
..forward();
didUpdateTweens();
}
}
3、使用 AnimatedContainer
创建一个 AnimatedContainer,将 transform 和 opacity 传入,设置 duration 时间是 500 ms
AnimatedContainer(
duration: Duration(milliseconds: 500),
transform: _transform,
child: AnimatedOpacity(
opacity: _opacity,
duration: Duration(milliseconds: 500),
child: Container(
alignment: Alignment.center,
width: 100,
height: 50,
color: Colors.pink,
),
),
)
4、改变默认的 样式
这里可以通过点击去改变
void _onTapHandle() {
setState(() {
_opacity = _opacity == 1.0 ? 0.0 : 1.0;
_transform = _opacity == 0.0
? Matrix4.translationValues(-300, 0, 0)
: Matrix4.translationValues(0, 0, 0);
});
}
5、最终的效果
在右下角我放了一个按钮,点击这个按钮,会改变上面的 Container 的动画效果
二、官方的 AnimatedContainer 动画
下面代码实现的是 CookBook 的渐变动画效果 https://flutter-io.cn/docs/cookbook/animation/animated-container.html
1、初始化 state
double _width = 60;
double _height = 60;
Color _color = Colors.pink;
Matrix4 _transform = null;
BorderRadius _borderRadius = BorderRadius.circular(8);
2、设置 state
CookBook 设置 state 的时候,更多的是区间随机,从颜色到宽度高度、甚至是边框圆角以及位置都是随机的,所以更能体现 AnimatedContainer 的效果
void _onTapHandle() {
Random random = new Random();
setState(() {
_width = random.nextInt(300).toDouble();
_height = random.nextInt(300).toDouble();
_borderRadius = BorderRadius.circular(random.nextInt(300).toDouble());
_color = Color.fromARGB(
255, random.nextInt(256), random.nextInt(256), random.nextInt(256));
_transform = Matrix4.translationValues(random.nextInt(50).toDouble(),
random.nextInt(50).toDouble(), random.nextInt(50).toDouble());
});
}
3、效果:
完整代码
- https://github.com/postbird/FlutterHelloWorldDemo/blob/master/demo1/lib/bak/main.46.2.AnimatedOpacity%20%26%20AnimatedContainer.dart
- https://github.com/postbird/FlutterHelloWorldDemo/blob/master/demo1/lib/bak/main.46-AnimatedContainer.dart
文章版权:Postbird-There I am , in the world more exciting!
本文链接:http://www.ptbird.cn/flutter-animatedcontainer.html
转载请注明文章原始出处 !