Flutter基建 - Hero动画有多英雄

本篇基于Flutter 3.16.4,Dart 3.2.3版本

Flutter 3.16.4 • channel stable • github.com/flutter/flu...

Framework • revision 2e9cb0aa71 (3 days ago) • 2023-12-11 14:35:13 -0700

Engine • revision 54a7145303

Tools • Dart 3.2.3 • DevTools 2.28.4

本篇为Flutter基建的第十篇文章💪🏻💪🏻💪🏻,主要介绍的是Flutter中Hero动画,Hero动画不仅仅在Flutter中存在,原生的Android包括Compose中都是有这个概念,它字面意思是英雄动画,其实就是在路由跳转(页面切换)时提供了一种类似飞行的效果,使得页面切换过渡非常丝滑和流畅的视角效果,最常用的场景为小图查看大图,下面一起进入文章的了解下吧~

Hero动画

我们就以点击小图然后跳转到大图界面为例,来看看Hero动画可以帮助我们实现什么样的效果。

列表界面

我们先来实现一个列表界面,列表中每个item展示一个Image和Text,然后对Image做Hero动画由小图飞行至大图。

scala 复制代码
class HeroAnimated extends StatelessWidget {
  const HeroAnimated({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text(
          "Hero Animated",
        ),
      ),
      body: ListView.builder(
        itemBuilder: (context, index) {
          return HeroItem(index);
        },
        itemCount: 20,
      ),
    );
  }
}

这里用ListView.builder实现一个列表组件,列表的item为HeroItem,传入参数index,此index是为了给Hero的tag所用。

arduino 复制代码
class HeroItem extends StatelessWidget {
  final int index;

  const HeroItem(this.index, {super.key});

  @override
  Widget build(BuildContext context) {
    return ListTile(
      title: Text('Item $index'),
      leading: Hero(
        createRectTween: (begin, end) {
          return RectTween(begin: begin, end: end);
        },
        tag: "hero-item-$index",
        child: const Image(
          image: AssetImage("images/img.png"),
        ),
      ),
      onTap: () {
        Navigator.push(
          context,
          MaterialPageRoute(
            builder: (context) {
              return SecHeroWidget(index);
            },
          ),
        );
      },
    );
  }
}

Item组件直接采用的是ListTile实现(主要是为了方便^-^),然后对内部Image做了一个Hero父组件包裹,注意这里Hero传入的参数:

  • createRectTween表示飞行过程中是以何种线条运动,我们传入的是RectTween它就会在小图和大图的矩形之间直接飞行过去,除了RectTween之外,还有MaterialRectArcTween和MaterialRectCenterArcTween两种,这两种在飞行的轨迹中都会有一个弧度,看起来动画效果更为精致一点,一会我们会分别展示下两种类型的效果;
  • tag参数非常重要,小图和大图的Hero tag参数必须保持一致,否则系统会找不到对应的大图无法执行动画,而且不可以一对多或者多对多,只可以一对一的形式;
  • child参数就是我们需要的小图,这里传入的是Image组件,不过多介绍。

写完列表界面之后,我们再来看看大图界面是如何实现的。

大图界面

php 复制代码
class ImageDetailWidget extends StatelessWidget {
  final int index;

  const ImageDetailWidget(this.index, {super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("ImageDetail"),
      ),
      body: Hero(
        createRectTween: (begin, end) {
          return RectTween(begin: begin, end: end);
        },
        tag: "hero-item-$index",
        child: const Center(
          child: Image(
            image: AssetImage("images/img.png"),
          ),
        ),
      ),
    );
  }
}

大图界面的逻辑就比较简单了,将小图对应的index传入,此index参数需要传入到Hero的key种,这样就能保证小图和大图的key对应起来,大图的tween也是和小图保持一致,接下来我们来看看实际的效果。

使用Hero动画之后,在页面切换的过程中可以看到小图和大图有一个逐渐放大和缩小的动画,比起直接跳转页面的视角效果要好看的多,但是RectTween这种方式给人的感觉还是有点生硬,下面我们将RectTween替换为MaterialRectArcTween再来看看效果。

写在最后

本篇文章主要介绍了Flutter中Hero动画的基本使用,文章内容比较简单,但是Hero动画在日常开发中可以帮助我们优化页面跳转的视角效果,还是比较实用的一个知识点,希望通过文章给阅读的小伙伴们带来一点帮助,后续会循序渐进逐步接触Flutter更多的知识。

我是Taonce,如果觉得本文对你有所帮助,帮忙关注、赞或者收藏三连一下,谢谢😆😆~

相关推荐
非凡ghost12 分钟前
海豚远程控制APP:随时随地,轻松掌控手机
android·智能手机·软件需求
G_whang4 小时前
jenkins自动化部署前端vue+docker项目
前端·自动化·jenkins
凌辰揽月6 小时前
AJAX 学习
java·前端·javascript·学习·ajax·okhttp
然我8 小时前
防抖与节流:如何让频繁触发的函数 “慢下来”?
前端·javascript·html
鱼樱前端8 小时前
2025前端人一文看懂 Broadcast Channel API 通信指南
前端·vue.js
还是奇怪8 小时前
Linux - 安全排查 3
android·linux·安全
烛阴8 小时前
非空断言完全指南:解锁TypeScript/JavaScript的安全导航黑科技
前端·javascript
鱼樱前端8 小时前
2025前端人一文看懂 window.postMessage 通信
前端·vue.js
Android采码蜂8 小时前
BLASTBufferQueue03-BufferQueueConsumer核心操作
android
快乐点吧9 小时前
【前端】异步任务风控验证与轮询机制技术方案(通用笔记版)
前端·笔记