Flutter Hero动画(2.5)

今天给大家介绍的是Flutter中独有的动画,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> {
  @override
  Widget 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 {
  @override
  Widget 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)

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

s10g

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值