系列文章
- Flutter 旋转动画 — RotationTransition
- Flutter 平移动画 — 4种实现方式
- Flutter 淡入淡出与逐渐出现动画
- Flutter 尺寸缩放、形状、颜色、阴影变换动画
- Flutter 列表Item动画 — AnimatedList实现Item左进左出、淡入淡出
- Flutter Hero 实现共享元素转场动画
- Flutter Hero 实现径向变换动画 — 圆形变成矩形的转场动画
- Flutter 自定义动画 — 数字递增动画和文字逐行逐字出现或消失动画
文章目录
1 平移动画效果图
2 动画基础知识
- Animation 是 Flutter 动画库中的核心类,它插入用于引导动画的值。
- AnimationController 管理动画。例如控制动画开始、停止、前进、后退等。
- CurvedAnimation 将进程定义为非线性曲线。
- Tween 在被动画对象使用的数据范围之间进行插值。 例如,Tween 可以定义从红色到蓝色或从 0 到 255 的插值。
- Listeners 和 StatusListeners 可监控动画状态的变化。
- AnimatedWidget 是展示动画的Widget,Flutter提供一些动画Widget让我们快速实现动画效果。例如:
AnimatedBuilder、 AnimatedModalBarrier、AlignTransition、DecoratedBoxTransition、FadeTransition、PositionedTransition、RelativePositionedTransition、RotationTransition、ScaleTransition、SizeTransition、SlideTransition
3 平移动画实现方式
Flutter提供了四个Widget可实现平移动画,分别是
- SlideTransition
- AlignTransition
- PositionedTransition
- RelativePositionedTransition
3.1 SlideTransition
SlideTransition 是基于 Animation<Offset> 来确定平移位置的。平移的具体距离,是由Widget自身的宽高 * Offset中的 x y 值。
例:Widget 的width=100,height = 200,平移动画的起点为Offset(0,0),终点 为Offset(2,3),则平移动画移动的宽度就是 width*dx = 100 *2 ;高度就是 height * dy= 200 *3
3.1.1 实现Widget从左上角平移到右下角
大概步骤:
- 创建 AnimationController
- 使用 LayoutBuilder 获取到容器的宽高
- 通过容器与子控件的宽高 计算出偏移量 Offset
- 创建补间动画 Tween<Offset>
- 使用 SlideTransition 实现平移动画
具体代码:
class SlideTransitionPage extends StatefulWidget {
const SlideTransitionPage({
Key? key}) : super(key: key);
@override
State<StatefulWidget> createState() => _SlideTransitionPageState();
}
class _SlideTransitionPageState extends State<SlideTransitionPage>
with SingleTickerProviderStateMixin {
late final AnimationController _controller;
@override
void initState() {
super.initState();
/// 重复播放,持续时间为5秒的动画控制器
_controller = AnimationController(
duration: const Duration(seconds: 5),
vsync: this,
)..repeat(reverse: true);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
/// 需要平移的Widget 宽高
const childHeight = 100.0;
const childWidth = 150.0;
/// 父布局的宽高
final parentWidth = constraints.maxWidth;
final parentHeight = constraints.ma