经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » Flutter » 查看文章
详解Android?Flutter如何自定义动画路由
来源:jb51  时间:2023/4/21 8:57:18  对本文有异议

简介

flutter中有默认的Route组件,叫做MaterialPageRoute,一般情况下我们在flutter中进行跳转的话,只需要向Navigator中传入一个MaterialPageRoute就可以了。

但是MaterialPageRoute太普通了,如果我们想要做点不同的跳转特效应该如何处理呢?

一起来看看吧。

自定义跳转使用

正常情况下,我们进行路由跳转需要用到Navigator和MaterialPageRoute,如下所示:

  1. Navigator.push(context, MaterialPageRoute(builder: (context) {
  2. return const NextPage();

如果要实现特定的路由动画,那么需要进行路由的自定义。

在flutter中也就是要使用PageRouteBuilder来自定义一个Route。

先来看下PageRouteBuilder的定义:

  1. class PageRouteBuilder<T> extends PageRoute<T> {
  2.  
  3. PageRouteBuilder({
  4. super.settings,
  5. required this.pageBuilder,
  6. this.transitionsBuilder = _defaultTransitionsBuilder,
  7. this.transitionDuration = const Duration(milliseconds: 300),
  8. this.reverseTransitionDuration = const Duration(milliseconds: 300),
  9. this.opaque = true,
  10. this.barrierDismissible = false,
  11. this.barrierColor,
  12. this.barrierLabel,
  13. this.maintainState = true,
  14. super.fullscreenDialog,
  15. })

PageRouteBuilder也是PageRoute的一种,在构建PageRouteBuilder的时候,通过控制不同的属性值,我们可以自由控制pageBuilder,transitionsBuilder,transitionDuration,reverseTransitionDuration等特性。

可以看到自由程度还是非常高的。

其中pageBuilder是路由将会跳转的页面,这个是必须要指定的,要不然路由也就没有意义了。

另外路由转换的效果可以经由transitionsBuilder来设置。

这里的RouteTransitionsBuilder是一个Function,返回一个Widget:

  1. typedef RouteTransitionsBuilder = Widget Function(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child);

所以理论上,我们可以返回任何widget,但是一般来说,我们会返回一个AnimatedWidget,表示一个动画效果。

flutter动画基础

flutter中有个专门的动画包叫做flutter/animation.dart, flutter中所有动画的核心叫做Animation。

Animation中定义了很多listener用来监控动画的变动情况,并且还提供了一个AnimationStatus来存储当前的动画状态:

  1. abstract class Animation<T> extends Listenable implements ValueListenable<T> {
  2. const Animation();
  3.  
  4. AnimationWithParentMixin<T>
  5.  
  6. @override
  7. void addListener(VoidCallback listener);
  8.  
  9. @override
  10. void removeListener(VoidCallback listener);
  11.  
  12. void addStatusListener(AnimationStatusListener listener);
  13.  
  14. void removeStatusListener(AnimationStatusListener listener);
  15.  
  16. AnimationStatus get status;

AnimationStatus是一个枚举类,它包含了现在动画的各种状态:

  1. enum AnimationStatus {
  2. dismissed,
  3.  
  4. forward,
  5.  
  6. reverse,
  7.  
  8. completed,
  9. }

dismissed表示动画暂停在开头。

forward表示动画在从头到尾播放。

reverse表示动画在从尾到头播放。

completed表示动画播放完毕,停在了结尾。

有了动画的表示之后,如何对动画进行控制呢?这里就需要用到AnimationController了。

AnimationController可以控制动画的duration,动画的最低值lowerBound默认是0.0,动画的最高值upperBound默认是1.0等等。

默认情况AnimationController中从最低值到最高值是线性变化的,如果你想设置不同的Bound值,那么可以尝试自定义 Animatable, 如果你想动画的变动是非线性的,那么可以尝试继承Animation来实现自己的变动曲线。

实现一个自定义的route

这里我们使用flutter中的SlideTransition,SlideTransition是一个AnimatedWidget,它表示的是一个组件的位置变化的动画。

  1. class SlideTransition extends AnimatedWidget {
  2. const SlideTransition({
  3. super.key,
  4. required Animation<Offset> position,
  5. this.transformHitTests = true,
  6. this.textDirection,
  7. this.child,
  8. }) : assert(position != null),
  9. super(listenable: position);

看下它的构造函数,可以看到SlideTransition需要一个position的属性,这个position是一个Animation对象,里面包含的是Offset。

同时这个position是一个listenable对象,通过监听里面Offset的变化,从而重新build对应的widget从而实现动画的效果。

Offset是一个表示位置的类,(0,0) 表示这个widget的左顶点在屏幕的左上角,同样的(1,1)表示这个widget的左顶点在屏幕的右下角。

因为route过后是一个新的页面,我们希望出现一个页面从右下角移动到左上角的动画,那么我们可以这样做:

  1. Route customRoute() {
  2. return PageRouteBuilder(
  3. pageBuilder: (context, animation, secondaryAnimation) => const SecondPage(),
  4. transitionsBuilder: (context, animation, secondaryAnimation, child) {
  5. const begin = Offset(1.0, 1.0);
  6. const end = Offset.zero;
  7. const curve = Curves.easeOut;
  8.  
  9. var tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
  10.  
  11. return SlideTransition(
  12. position: animation.drive(tween),
  13. child: child,
  14. );
  15. },
  16. );
  17. }

这里的begin和end表示widget从屏幕的右下角移动到了屏幕的左上角。

Tween表示的是开始值和结束值之间的线性插值,是一个动态过程,另外我们还可以这个插值变动的曲线,这里使用了CurveTween,选中了Curves.easeOut这种曲线类型。

最后调用animation.drive方法把Tween和Animation关联起来,这样一个路由动画就完成了。

总结

最后程序运行的结果如下:

其实flutter中的动画很简单,大家记住就是widget位置沿不同的曲线变化即可。

本文的例子:github.com/ddean2009/learn-flutter

以上就是详解Android Flutter如何自定义动画路由的详细内容,更多关于Android Flutter自定义动画路由的资料请关注w3xue其它相关文章!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号