Flutter Hero动画(2.5)

今天给大家介绍的是Flutter中独有的动画,Hero动画,非常的炫酷,接下来就步入正题吧~

  • Hero动画介绍

Hero动画介绍

Hero指的是可以在路由(页面)之间“飞行”的widget,简单来说Hero动画就是在路由切换时,有一个共享的widget可以在新旧路由间切换。由于共享的widget在新旧路由页面上的位置、外观可能有所差异,所以在路由切换时会从旧路逐渐过渡到新路由中的指定位置,这样就会产生一个Hero动画。

Flutter中文网参考

先来看看要完成的效果吧:

效果图(1.1):

在这里插入图片描述

分析:

通过效果图可以看出,点击图片或者文字,完成了图片的由小到大的动画效果,并且完成了页面的切换,以及文字布局在不同位置的展示, 水波纹点击效果

好了,咋们先不考虑Hero动画如何使用,先把2个页面的布局,图片,文字给写出来,以及水波纹效果

class HerpPracticePage extends StatefulWidget {@override_HerpPracticePageState createState() => _HerpPracticePageState();
}class _HerpPracticePageState extends State<HerpPracticePage> {@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("Hero动画练习"),),body: Container(color: Colors.transparent,//左右排列布局child: Material(//水波纹效果child: InkWell(onTap: () {},child: Row(//主轴方向开始对齐 在这里是左对齐mainAxisAlignment: MainAxisAlignment.start,//交叉轴上开始对齐 在这里是顶部对齐crossAxisAlignment: CrossAxisAlignment.start,children: [//左侧图片initLeftIcon(),//右侧文字initRightTxt(),],),)),),);}/*** 左侧图片*/Widget initLeftIcon() {return Container(child: Image.network("https://raw.githubusercontent.com/flutter/website/master/examples/_animation/hero_animation/images/flippers-alpha.png",width: 150,height: 80,),);}/*** 右侧文字*/Widget initRightTxt() {//建议使用Expanded包裹,这样防止上下布局Text文本溢出导致错误!return Expanded(child: Column(crossAxisAlignment: CrossAxisAlignment.start,mainAxisSize: MainAxisSize.min,children: [Text("今天礼拜六"),Text("我在公司认真的学习flutter,正在学习Hero动画,有点难,不过我会克服的!!"),],));}}

这段代码十分简单,先通过Row()组件完成布局的左右(水平)排列,

将图片和文字区分开,

然后在在文字区域使用Cloumn()组件完成布局的上下(垂直)排列,

将文字上下排列开

然后在使用InkWell设置水波纹效果

这里有2处地方需要注意:

  • 使用Inkwell一定要写OnTap(){}单击事件属性
  • 在使用Column()组件时建议用Expanded()包裹一下,若Column()组件屏幕溢出,则会报错,Expanded()会展开,常用于占满父容器垂直高度,同样在使用Row()组件的时候也可以使用

跳转到的页面:

class JumpPage extends StatelessWidget {@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("这是跳转页面"),),body: initJumpPageBody(context),);}/*** JumpPage的Body布局*/initJumpPageBody(BuildContext context) {return Container(child: Column(children: [//图片initJumpIcon(context),//文本initJumpTxt(context),],),);}/*** 初始化Jump图片布局*/initJumpIcon(BuildContext context) {return Material(child: InkWell(onTap: () {//返回上一页面Navigator.of(context).pop();},child: Image.network("https://raw.githubusercontent.com/flutter/website/master/examples/_animation/hero_animation/images/flippers-alpha.png",width: 300,height: 160,),),);}/*文字布局
*/initJumpTxt(BuildContext context) {return Container(padding: EdgeInsets.all(20),child: Text("我在公司认真的学习flutter,正在学习Hero动画,有点难,不过我会克服的!!",),);}
}

这段代码更不需要过多解释,就是一张图片,和一段文字

接下来就到了关键的时候,两个界面都初始化完成了,之后使用Hero()组件进行包裹

我们需要进行的是2个图片之间的’飞’,所以只需要对图片使用Hero()组件即可

第一个页面图片添加Hero()组件,并添加Tag

 /*** 左侧图片*/Widget initLeftIcon() {return Container(child: Hero(tag: "HeroPractice",child: Image.network("https://raw.githubusercontent.com/flutter/website/master/examples/_animation/hero_animation/images/flippers-alpha.png",width: 150,height: 80,),),);}

跳转到的页面图片:

 /*** 初始化Jump图片布局*/initJumpIcon(BuildContext context) {return InkWell(onTap: () {Navigator.of(context).pop();},child: Hero(tag: "HeroPractice",child: Image.network("https://raw.githubusercontent.com/flutter/website/master/examples/_animation/hero_animation/images/flippers-alpha.png",width: 300,height: 160,),),);}

这里需要注意的是:

  • Hero()中tag参数是2个页面之间的唯一标识,不能重复且唯一的!!!
  • 我看有些博客写Hero()中子组件必须用Material()包裹,可能版本不一样,我使用的过程中不包裹也可以.如若报错,加上试试吧~
  • 在使用Hero()的时候,一定不能包裹太多的子组件,否则的话就会有这种效果,请看效果图(1.2)

效果图(1.2):
在这里插入图片描述
从效果图(1.2)中可以看出,点击跳转时,图片背景会有一层白色的状态,然而返回的时候并没有,这就是Hero()包裹太多子组件导致的,别问我怎么知道的,我心里苦o(╥﹏╥)o…(下一章这里有妙用!!!)

现在已经完成了70%,现在只需要完成在2秒内跳转中的动画,由不透明==>>透明即可大功告成!
这里只需要在跳转页面时使用PageRouteBuilder自定义路由即可

onTap: () {//跳转页面Navigator.of(context).push(initPageRouteBuilder());},/*** 初始化跳转页面参数*/Route<Object> initPageRouteBuilder() {return PageRouteBuilder(pageBuilder: (BuildContext context, Animation<double> animation,Animation<double> secondaryAnimation) {//设置跳转到的页面return JumpPage();},//打开新页面的时间transitionDuration: Duration(seconds: 2),//关闭页面的时间reverseTransitionDuration: Duration(seconds: 2),//跳转页面的动画transitionsBuilder: (BuildContext context, Animation<double> animation,Animation<double> secondaryAnimation, Widget child) {//跳转页面动画> 这里是引用return initFadeTransition(animation, child);},);}

PageRouteBuilder自定义路由,加粗是必加参数

PageRouteBuilder参数类型说明
pageBuilderRoutePageBuilder一般用来返回跳转页面
transitionDurationDuration用来设置打开新页面的时间
reverseTransitionDurationDuration关闭页面的时间
transitionsBuilderRoutePageBuilder用来设置动画

跳转页面动画:

  /*** 透明动画*/Widget initFadeTransition(Animation<double> animation, Widget child) {return FadeTransition(opacity: Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation(parent: animation,curve: Curves.linear,)),child: child,);}

这段代码在Flutter AnimatedWidget,AnimatedBuilder动画(2.4)讲过类似的,当时是获取的帧,现在只是透明度变化,没有什么区别,这里就不在重复说啦

完整代码

上一章:Flutter AnimatedWidget,AnimatedBuilder动画(2.4)

下一章:Flutter Hero动画(2.6)

原创不易,您的点赞就是对我最大的支持,留下您的点赞吧~


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部