flutter中的过场动画 PageTransitionsTheme
文章目录
过场动画
过场动画也就是切换路由时的动画
这个东西有几种方案可以做
- 继承
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属性
1
2class MyApp extends StatelessWidget {
3 // This widget is the root of your application.
4 @override
5 Widget build(BuildContext context) {
6 return MaterialApp(
7 title: 'Flutter Demo',
8 theme: ThemeData(
9 primarySwatch: Colors.blue,
10 pageTransitionsTheme: PageTransitionsTheme(
11 builders: <TargetPlatform, PageTransitionsBuilder>{
12 TargetPlatform.iOS: createTransition(),
13 TargetPlatform.android: createTransition(),
14 },
15 ),
16 ),
17 home: MyHomePage(title: 'Flutter Demo Home Page'),
18 );
19 }
20}
使用系统提供的一些动画
1
2PageTransitionsBuilder createTransition() {
3 return FadeUpwardsPageTransitionsBuilder();
4}
效果如下:
根据注释, sdk 中有如下几种动画
其中FadeUpwardsPageTransitionsBuilder对应安卓默认的, PageTransitionsBuilder自然是对应的 iOS
ZoomPageTransitionsBuilder:
OpenUpwardsPageTransitionsBuilder:
自定义
除了已有的, 我们还可以自定义动画, 可以配合 animation 组件来完成酷炫的动画效果, 具体的可以查看 官网动画部分介绍
自定义 MyPageTransitionsBuilder
1import 'package:flutter/material.dart';
2
3PageTransitionsBuilder createTransition() {
4 // return FadeUpwardsPageTransitionsBuilder();
5 // return OpenUpwardsPageTransitionsBuilder();
6 // return ZoomPageTransitionsBuilder();
7 return MyPageTransitionsBuilder();
8}
9
10class MyPageTransitionsBuilder extends PageTransitionsBuilder {
11 @override
12 Widget buildTransitions<T>(
13 PageRoute<T> route,
14 BuildContext context,
15 Animation<double> animation,
16 Animation<double> secondaryAnimation,
17 Widget child) {
18 return ScaleTransition(
19 scale: animation,
20 child: RotationTransition(
21 turns: animation,
22 child: child,
23 ),
24 );
25 }
26}
效果如下
后记
有问题请在本人 博客 下留言(github 登陆即可)