老孟导读:今天分享一个类似“孔雀开屏”的动画效果,打开新的页面时,新的页面从屏幕右上角以圆形逐渐打开到全屏。

先来看下具体的效果

不知道这种效果大家叫什么名字?如果有更合适的名字可以在评论处告诉我,下面来说下如何实现此效果。

在使用Navigator进入一个新的页面时,通常用法如下:

Navigator.of(context).push(MaterialPageRoute(
builder: (context){
return PageB();
}
));

MaterialPageRoute就包含了切换页面时的动画效果,在iOS上效果是左右滑动切换,在Android上效果是上下滑动,如果想要自定义切换效果如何实现呢?答案是使用PageRouteBuilder,用法如下:

Navigator.of(context).push(PageRouteBuilder(pageBuilder:
(BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation) {
...
}));

pageBuilder函数中使用animation返回新页面的动画效果即可。

新的页面以圆形效果逐渐打开,注意并没有缩放效果,所以新的页面是被裁减的,新的页面以右上角为圆心,半径逐渐变大进行裁切,就是我们想要的效果。

通过上面的分析,使用ClipPath对新的页面进行裁切

Navigator.of(context).push(PageRouteBuilder(pageBuilder:
(BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation) {
return AnimatedBuilder(
animation: animation,
builder: (context, child) {
return ClipPath(
clipper: CirclePath(animation.value),
child: child,
);
},
child: PageB(),
);
}));

重点是CirclePath,这就是裁切的路径,

class CirclePath extends CustomClipper<Path> {
CirclePath(this.value); final double value; @override
Path getClip(Size size) {
var path = Path();
double radius =
value * sqrt(size.height * size.height + size.width * size.width);
path.addOval(Rect.fromLTRB(
size.width - radius, -radius, size.width + radius, radius));
return path;
} @override
bool shouldReclip(CustomClipper<Path> oldClipper) {
return true;
}
}

由于Path没有直接添加圆形的API函数,因此使用椭圆方法,只需将椭圆的矩形区域设置为正方形,那么裁切出来的就是圆形。

半径的最大值并不是屏幕的宽或者高,而是屏幕的对角线长度。

由于是从右上角开始,而且裁切的矩形区域必须是正方形,所以裁切的矩形区域是超出页面区域的。

如果很多页面都用到了这个效果,可以进行封装,类似于MaterialPageRoute,封装如下:

class CirclePageRoute extends PageRoute {
CirclePageRoute({
@required this.builder,
this.transitionDuration = const Duration(milliseconds: 500),
this.opaque = true,
this.barrierDismissible = false,
this.barrierColor,
this.barrierLabel,
this.maintainState = true,
}); final WidgetBuilder builder; @override
final Duration transitionDuration; @override
final bool opaque; @override
final bool barrierDismissible; @override
final Color barrierColor; @override
final String barrierLabel; @override
final bool maintainState; @override
Widget buildPage(BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation) {
return AnimatedBuilder(
animation: animation,
builder: (context, child) {
return ClipPath(
clipper: CirclePath(animation.value),
child: child,
);
},
child: builder(context),
);
}
}

使用

Navigator.of(context).push(CirclePageRoute(builder: (context) {
return PageB();
}));

如果你查看CupertinoPageRouteMaterialPageRoutePageRouteBuilder的源码,你会发现这3个都是继承自PageRoute,所以,不知不觉我们又学会了自定义路由。

交流

老孟Flutter博客地址(近200个控件用法):http://laomengit.com

欢迎加入Flutter交流群(微信:laomengit)、关注公众号【老孟Flutter】:

Flutter “孔雀开屏”的动画效果的更多相关文章

  1. Flutter酷炫的路由动画效果

    现在Flutter的路由效果已经非常不错了,能满足大部分App的需求,但是谁不希望自己的App更酷更炫那,下面介绍几个酷炫的路由动画. 其实路由动画的原理很简单,就是重写并继承PageRouterBu ...

  2. 【Flutter 实战】酷炫的开关动画效果

    此动画效果是我在浏览文章时发现的一个非常酷炫的效果,于是就使用 Flutter 实现了. 更多动画效果及Flutter资源:https://github.com/781238222/flutter-d ...

  3. 【Flutter学习】之动画实现原理浅析(三)

    一,概述 Flutter动画库的核心类是Animation对象,它生成指导动画的值,Animation对象指导动画的当前状态(例如,是开始.停止还是向前或者向后移动),但它不知道屏幕上显示的内容.动画 ...

  4. 【Flutter学习】之动画实现原理浅析(二)

    1. 介绍 本文会从代码层面去介绍Flutter动画,因此不会涉及到Flutter动画的具体使用. 1.1 Animation库 Flutter的animation库只依赖两个库,Dart库以及phy ...

  5. 【Flutter学习】之动画实现原理浅析(一)

    一,动画介绍 动画对于App来说,非常的重要.很多App,正是因为有了动画,所以才会觉得炫酷.移动端的动画库有非常的多,例如iOS上的Pop.web端的animate.css.Android端的And ...

  6. 【Flutter 实战】自定义动画-涟漪和雷达扫描

    老孟导读:此篇文章是 Flutter 动画系列文章第五篇,本文介绍2个自定义动画:涟漪和雷达扫描效果. 涟漪 实现涟漪动画效果如下: 此动画通过 CustomPainter 绘制配合 Animatio ...

  7. app引导页(背景图片切换加各个页面动画效果)

    前言:不知不觉中又加班到了10点半,整个启动页面做了一天多的时间,一共有三个页面,每个页面都有动画效果,动画效果调试起来麻烦,既要跟ios统一,又要匹配各种不同的手机,然后产品经理还有可能在中途改需求 ...

  8. Android动画效果之自定义ViewGroup添加布局动画

    前言: 前面几篇文章介绍了补间动画.逐帧动画.属性动画,大部分都是针对View来实现的动画,那么该如何为了一个ViewGroup添加动画呢?今天结合自定义ViewGroup来学习一下布局动画.本文将通 ...

  9. Android动画效果之Property Animation进阶(属性动画)

    前言: 前面初步认识了Android的Property Animation(属性动画)Android动画效果之初识Property Animation(属性动画)(三),并且利用属性动画简单了补间动画 ...

随机推荐

  1. CF思维联系–CodeForces - 225C. Barcode(二路动态规划)

    ACM思维题训练集合 Desciption You've got an n × m pixel picture. Each pixel can be white or black. Your task ...

  2. Dubbo(六):zookeeper注册中心的应用

    Dubbo中有一个非常本质和重要的功能,那就是服务的自动注册与发现,而这个功能是通过注册中心来实现的.而dubbo中考虑了外部许多的注册组件的实现,zk,redis,etcd,consul,eurek ...

  3. SpringCloud (一) :微服务架构

    什么是微服务架构 简而言之,微服务架构风格就是将单一应用的开发分为多个小的服务,每个小的服务在自己的进程中运行并使用轻量级机制进行通信(通常是一个HTTP API源),这些服务围绕业务性能进行构建,并 ...

  4. Kafka 的一些知识点整理【1】

    First: Kafka 是什么? Kafka 是一个发布订阅系统 最初是是LinkedIn 开发 最后交给Apache 开源组织 github地址:https://github.com/apache ...

  5. Java 设置PDF中的文本旋转、倾斜

    本文介绍通过Java程序在PDF文档中设置文本旋转.倾斜的方法.设置文本倾斜时,通过定义方法TransformText(page);并设置page.getCanvas().skewTransform( ...

  6. js数据类型很简单,却也不简单

    最近脑子里有冒出"多看点书"的想法,但我个人不是很喜欢翻阅纸质书籍,另一方面也是因为我能抽出来看书的时间比较琐碎,所以就干脆用app看电子书了(如果有比较完整的阅读时间,还是建议看 ...

  7. C# 数据操作系列 - 3. ADO.NET 离线查询

    0. 前言 在上一篇中,我故意留下了查询的示范没讲.虽然说可以通过以下代码获取一个DataReader: IDataReader reader = command.ExecuteReader(); 然 ...

  8. input在IOS中的聚焦问题

    关于input输入框在iPhone手机中的聚焦问题,开发中是会经常遇到的,在一般的浏览器中,我们一般是通过 document.getElementById('opop').focus(); 来获取焦点 ...

  9. 图形学_opengl纹理映射

    学了半学期的图形学,除了几个用python或是matlab比较方便的实验外,用的大多数是opengl,在这总结一下纹理贴图实验中opengl的用法. 1.编译器连接静态库 有用到glaux.h的程序, ...

  10. BufferedInputStream:字节缓冲输入流

    package com.itheima.demo01.BufferedStream; import java.io.BufferedInputStream; import java.io.FileIn ...