刚刚看了一下flutter的路由动画文档,地址是:page-route-animation
PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => Page2(),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
var begin = Offset(0.0, -1.0);
var end = Offset.zero;
var curve = Curves.ease;
var tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
return SlideTransition(
position: animation.drive(tween),
child: child,
);
},
)
针对动画,学习了两点:
- Flutter offset的值是怎么回事,1 0 -1分别代表什么,我整理了一下,如图:
我来解读一下,
1. 页面显示在屏幕时,Offset的dx dy均为0;
2. 如果需要动画页面从屏幕底部弹出,则应该是dy=1 到 dy=0;
3. 如果需要动画页面从右侧推入到屏幕,则应该是dx=1 到 dx=0;
4. 如果需要动画页面从屏幕顶部弹出,则应该是dy=0 到 dy=-1
5. 其他类似
建议大家使用文档里的案例操作实验一下,加深印象。学习了这个,在写动画时就不会出现乱套的情况了。
- secondaryAnimation是干嘛用的呢?
写过安卓的都清楚有进场和出场动画,overridexxxx,那flutter只通过上面这段代码怎么实现出场,就给了一个child,很是奇怪。然后我发现secondaryAnimation还没用,是干嘛的?翻阅的一些文档: buildTransitions
看到了使用方式:
transitionsBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child,
) {
return SlideTransition(
position: AlignmentTween(
begin: const Offset(0.0, 1.0),
end: Offset.zero,
).animate(animation),
child: SlideTransition(
position: TweenOffset(
begin: Offset.zero,
end: const Offset(0.0, 1.0),
).animate(secondaryAnimation),
child: child,
),
);
}
刚看到我是很惊讶的,这是个怎么操作法?进出都套在了一个child上,到底怎么运行的呢?一开始我猜想难道是源码使用的地方会取出child的child?看了源码后,我觉得设计真巧妙!!
首先介绍下这两个动画常量(animation.dart中,目的就是保持动画终止位置和保持动画起始位置):
kAlwaysCompleteAnimation // The animation is stopped at the end
kAlwaysDismissedAnimation // The animation is stopped at the beginning
看到这里大家可能会有点明白了,两个animation是不是用上面两个常量,来切换使用做到每次只运行一个的呢?
然后我用下面的动画(一段动画,新页面从右侧屏幕滑入,旧页面从屏幕左侧滑出),打印了一下对应的回调:
SlideTransition(
position: Tween<Offset>(
begin: const Offset(1.0, 0.0),
end: Offset.zero,
).animate(animation),
child: SlideTransition(
position: Tween<Offset>(
begin: Offset.zero,
end: const Offset(-1.0, 0.0),
).animate(secondAnimation),
child: child,
),
)
得到的log,简化后:
animation | sencondaryAnimation |
---|---|
AnimationController#1c77c(▶ 0.335 | kAlwaysDismissedAnimation |
AnimationController#fc1fe(⏭ 1.000 | AAnimationController#1c77c(▶ 0.335 |
AnimationController#1c77c(▶ 0.535 | kAlwaysDismissedAnimation |
AnimationController#fc1fe(⏭ 1.000 | AAnimationController#1c77c(▶ 0.535 |
AnimationController#1c77c(⏭ 1.000 | kAlwaysDismissedAnimation |
AnimationController#fc1fe(⏭ 1.000; | AnimationController#1c77c⏭ 1.000 |
先只看#1c77c这个animation:
发现第一个参数是从0-1做的动画,第二个参数是保持不变在start状态即Offset.zero
,即通过改变第一个widge的位置,来实现界面从右侧滑入,第二个widget一直保持可见状态。
再来看下fc1fe这个animation,发现这个动画是第一个widge保持在end状态即Offset.zero
(屏幕上),第二个动画是从0-1运行,即offset.dx从0 -> -1,也就是页面从屏幕往左侧滑出的动画。
由以上,我们可以得出结论,animation参数值是用来给新push的页面做进场动画的,secondaryAnimation是给前页面做出厂动画的,灵活运用两个动画的变化值来实现动画,参数只需要一个child即可,我也从中学习了一种新的思路,建议大家也测试感受下。