
老孟导读:今天分享一个类似“孔雀开屏”的动画效果,打开新的页面时,新的页面从屏幕右上角以圆形逐渐打开到全屏。
先来看下具体的效果
不知道这种效果大家叫什么名字?如果有更合适的名字可以在评论处告诉我,下面来说下如何实现此效果。
在使用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> 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> secondaryAnimation) { return AnimatedBuilder( animation: animation,child) { return ClipPath( clipper: CirclePath(animation.value),); },child: builder(context),); }}使用
Navigator.of(context).push(CirclePageRoute(builder: (context) { return PageB();}));如果你查看CupertinopageRoute、MaterialPageRoute、PageRouteBuilder的源码,你会发现这3个都是继承自PageRoute,所以,不知不觉我们又学会了自定义路由。
老孟Flutter博客地址(近200个控件用法):http://laomengit.com
欢迎加入Flutter交流群(微信:laomengit)、关注公众号【老孟Flutter】:
以上是内存溢出为你收集整理的Flutter “孔雀开屏”的动画效果全部内容,希望文章能够帮你解决Flutter “孔雀开屏”的动画效果所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)