过场动画
过场动画也就是切换路由时的动画
这个东西有几种方案可以做
- 继承
PageRoute来做, 复写 5 个抽象方法, 并抽象buildTransitions - 继承已有的系统类, 比如 MaterialPageRoute 或者 CupertinoPageRoute
- 一劳永逸的方案, 使用
PageTransitionsTheme类结合 MaterialApp 的 theme 的pageTransitionsTheme属性
前两种目前网络上也有一些人做了分享, 但第三种好像很少有人使用, 我这里就来说一下PageTransitionsTheme的用法
这东西有如下的好处:
- 设置一次, 你所有的
MaterialPageRoute都可以生效 - 对于命名路由, 也就是
pushNamed体系的也有效
先分析下源码
为啥分析源码? 因为如果上来就用显得不高端
先找一个大家都知道的切入点, 一般的过场动画都是用的 Navigator.push 方法来实现的
看看方法里的实现, 会发现很多常见的东西, 比如, 每一个 Route 都有自己的 OverlayEntry
然后会有一个 install 方法
而实际调用中, 这个 Overlay 会被插入到 Overlay 栈内, 从而在界面上显示
经过这一串的调用, 就把 Navigator push 和 Route 关联到了一起, 那么 theme 是怎么和 Route 关联起来的呢, 我们进入 MaterialPageRoute 看一下
我们看到, 这里是从 Theme 中找到 pageTransitionsTheme, 然后调用 pageTransitionsTheme 的 buildTransitions 方法来完成构建, 所以这就是我们可以在 theme 中一次修改, 多处生效的主因了
如何使用
前面查看到了源码是如何关联到 pageTransitionsTheme 属性的, 我们接着就是该自定义的时候了
修改自己的 MyApp, 修改pageTransitionsTheme属性
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
pageTransitionsTheme: PageTransitionsTheme(
builders: <TargetPlatform, PageTransitionsBuilder>{
TargetPlatform.iOS: createTransition(),
TargetPlatform.android: createTransition(),
},
),
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
使用系统提供的一些动画
PageTransitionsBuilder createTransition() {
return FadeUpwardsPageTransitionsBuilder();
}
效果如下:
根据注释, sdk 中有如下几种动画
其中FadeUpwardsPageTransitionsBuilder对应安卓默认的, PageTransitionsBuilder自然是对应的 iOS
ZoomPageTransitionsBuilder:
OpenUpwardsPageTransitionsBuilder:
自定义
除了已有的, 我们还可以自定义动画, 可以配合 animation组件来完成酷炫的动画效果, 具体的可以查看官网动画部分介绍
自定义 MyPageTransitionsBuilder
import 'package:flutter/material.dart';
PageTransitionsBuilder createTransition() {
// return FadeUpwardsPageTransitionsBuilder();
// return OpenUpwardsPageTransitionsBuilder();
// return ZoomPageTransitionsBuilder();
return MyPageTransitionsBuilder();
}
class MyPageTransitionsBuilder extends PageTransitionsBuilder {
@override
Widget buildTransitions<T>(
PageRoute<T> route,
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child) {
return ScaleTransition(
scale: animation,
child: RotationTransition(
turns: animation,
child: child,
),
);
}
}
效果如下
后记
有问题请在本人博客下留言(github 登陆即可)
来源:CSDN
作者:做人要简单
链接:https://blog.csdn.net/qq_28478281/article/details/104486036