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:
自定义
除了已有的, 我们还可以自定义动画, 可以配合 组件来完成酷炫的动画效果, 具体的可以查看
自定义 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 登陆即可)