Flutter Hero动画让你的APP页面切换充满动效 不一样的体验 不一样的细节处理

优美的应用体验 来自于细节的处理,更源自于码农的自我要求与努力,当然也需要码农年轻灵活的思维。


本文章实现的Demo效果,如下图所示:
在这里插入图片描述

1 首先是页面的主体

在这里使用的是Scaffold脚手架来构建,代码如下:

class HeroHomePage extends StatefulWidget {
  @override
  _TestPageState createState() => _TestPageState();
}

class _TestPageState extends State<HeroHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      //背景
      backgroundColor: Colors.grey[200],
      //标题
      appBar: AppBar(
        title: Text("每日分享"),
      ),
      //页面主体
      body: buildBodyWidget(),
    );
  }
  ...
}

页面的主体就是这里显示的图文,使用Row来将图片与文本区域左右排列,代码如下:
在这里插入图片描述

  Widget buildBodyWidget() {
    //水波纹点击事件监听
    return InkWell(
      //手指点击抬起时的回调
      onTap: () {
        //打开新的页面
        openPageFunction();
      },
      child: Container(
        padding: EdgeInsets.all(10),
        color: Colors.white,
        //线性布局左右排列
        child: Row(
          //主轴方向开始对齐 在这里是左对齐 
          mainAxisAlignment: MainAxisAlignment.start,
          //交叉轴上开始对齐 在这里是顶部对齐
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            //左侧的图片
            buildLeftImage(),
            //右侧的文本区域
            buildRightTextArea()],
        ),
      ),
    );
  }

2 显示图片的构建

左侧的图片区域 需要 使用 Hero 来包裹,因为这里就是Hero动画触发的效果,代码如下:

  ///左侧的图片区域
  Container buildLeftImage() {
    return Container(
      margin: EdgeInsets.only(right: 12),
      child: Hero(
        tag: "test",
        child: Image.asset(
          "images/banner3.webp",
          width: 96,
          fit: BoxFit.fill,
          height: 96,
        ),
      ),
    );
  }

3 右侧的文本区域

在这里插入图片描述

  ///右侧的文本区域
  Expanded buildRightTextArea() {
    return Expanded(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        mainAxisSize: MainAxisSize.min,
        children: [
          Text(
            "优美的应用",
            softWrap: true,
            overflow: TextOverflow.ellipsis,
            maxLines: 3,
            style: TextStyle(fontSize: 16),
          ),
          Text(
            "优美的应用体验 来自于细节的处理,更源自于码农的自我要求与努力,当然也需要码农年轻灵活的思维。",
            softWrap: true,
            overflow: TextOverflow.ellipsis,
            maxLines: 3,
            style: TextStyle(fontSize: 14, color: Colors.black38),
          )
        ],
      ),
    );
  }

4 自定义透明过度动画路由

Hero达成两个页面之间共享元素的连动效果,但是页面的切换效果造成碍眼的体验,配合一个透明过度,达成舒适的体验,代码如下:

  ///自定义路由动画
  void openPageFunction() {
    Navigator.of(context).push(
      PageRouteBuilder(
        pageBuilder: (BuildContext context, Animation<double> animation,
            Animation<double> secondaryAnimation) {
          //目标页面
          return DetailsPage();
        },
        //打开新的页面用时
        transitionDuration: Duration(milliseconds: 1800),
        //关半页岩用时
        reverseTransitionDuration: Duration(milliseconds: 1800),
        //过渡动画构建
        transitionsBuilder: (
          BuildContext context,
          Animation<double> animation,
          Animation<double> secondaryAnimation,
          Widget child,
        ) {
          //渐变过渡动画
          return FadeTransition(
            // 透明度从 0.0-1.0
            opacity: Tween(begin: 0.0, end: 1.0).animate(
              CurvedAnimation(
                parent: animation,
                //动画曲线规则,这里使用的是先快后慢
                curve: Curves.fastOutSlowIn,
              ),
            ),
            child: child,
          );
        },
      ),
    );
  }

5 最后就是点击图文信息打开的详情页面

class DetailsPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      //背景透明
      backgroundColor: Colors.white,
      appBar: AppBar(
        title: Text("精彩人生"),
      ),
      body: buildCurrentWidget(context),
    );
  }

  Widget buildCurrentWidget(BuildContext context) {
    return Container(
      color: Colors.white,
      padding: EdgeInsets.all(8),
      margin: EdgeInsets.all(10),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          //图片区域
          buildHero(context),
          SizedBox(
            width: 22,
          ),
          //文字区域
          buildTextContainer(),
        ],
      ),
    );
  }
}

页面分为两部分,第一部分的图片,使用Hero过渡 ,需要注意的是 目标 Hero 的直接子类必须是一个 Material包裹,代码如下:

  ///图片区域
  Hero buildHero(BuildContext context) {
    return Hero(
      tag: "test",
      child: Material(
        color: Colors.blue,
        child: InkWell(
          onTap: () {
            Navigator.of(context).pop();
          },
          child: Image.asset(
            "images/banner3.webp",
            fit: BoxFit.fill,
          ),
        ),
      ),
    );
  }

第二部分就是一个普通的文本了


  Container buildTextContainer() {
    return Container(
      child: Text(
        "优美的应用体验 来自于细节的处理,更源自于码农的自我要求与努力",
        softWrap: true,
        overflow: TextOverflow.ellipsis,
        maxLines: 3,
        style: TextStyle(fontSize: 16),
      ),
    );
  }

Flutter Hero动画 让你的APP页面切换充满动效 不一样的体验 优美的视觉

【x1】微信公众号的每日提醒 随时随记 每日积累 随心而过 文章底部扫码关注

【x2】各种系列的视频教程 免费开源 关注 你不会迷路

【x3】系列文章 百万 Demo 随时 复制粘贴 使用

【x4】一目了然的源码

【x5】简短的视频不一样的体验


不局限于思维,不局限语言限制,才是编程的最高境界。

以小编的性格,肯定是要录制一套视频的,随后会上传

有兴趣 你可以关注一下 西瓜视频 — 早起的年轻人

在这里插入图片描述

早起的年轻人 CSDN认证博客专家 移动开发 项目管理 Java
只要用心去做,每一件事情还是有可能成功的,当然成功是没有界限的,只不过是达到自己心里的那个目标,公众号:我的大前端生涯,一个爱喝茶的程序员,通常会搞搞SpringBoot 、Herbinate、Mybatiys、Android、iOS、Flutter、Vue、小程序等.
©️2020 CSDN 皮肤主题: 代码科技 设计师:Amelia_0503 返回首页