31、Flutter之Hero动画

Flutter Hero动画

  • Hero指的是可以在路由(页面)之间“飞行”的widget。
  • 使用Flutter的Hero widget创建hero动画。
  • 将 hero从一个路由飞到另一个路由。
  • 将 hero 的形状从圆形转换为矩形,同时将其从一个路由飞到另一个路由的过程中进行动画处理。
  • Flutter中的Hero widget实现了通常称为 共享元素转换共享元素动画的动画风格。

你可能多次看过 hero 动画。例如,路由显示代表待售物品的缩略图列表。选择一个条目会将其跳转到一个新路由,新页面中包含更多详细信息和“购买”按钮。 在Flutter中将图片从一个路由飞到另一个路由称为hero动画,尽管相同的动作有时也称为 共享元素转换

Hero动画的基本结构

  • 在不同路由中使用两个 hero widget,但使用匹配的标签来实现动画。
  • 导航器管理包含应用程序路由的栈。
  • 从导航器栈中推入或弹出路由会触发动画。
  • Flutter框架会计算一个补间矩形 ,用于定义在从源路由“飞行”到目标路由时 hero 的边界。在“飞行”过程中, hero 会移动到应用程序上的一个叠加层,以便它出现在两个页面之上。

示例

假设有两个路由A和B,他们的内容交互如下:

A:包含一个用户头像,圆形,点击后跳到B路由,可以查看大图。

B:显示用户头像原图,矩形。

在AB两个路由之间跳转的时候,用户头像会逐渐过渡到目标路由页的头像上,接下来我们先看看代码:

import 'package:flutter/material.dart';

class HeroAnimationRoute extends StatelessWidget {
  const HeroAnimationRoute({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        padding: EdgeInsets.only(top: 100),
        alignment: Alignment.topCenter,
        child: Column(
          children: <Widget>[
            InkWell(
              child: Hero(
                tag: "avatar", //唯一标记,前后两个路由页Hero的tag必须相同
                child: ClipOval(
                  child: Image.network('https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.jj20.com%2Fup%2Fallimg%2F511%2F101611154647%2F111016154647-10-1200.jpg&refer=http%3A%2F%2Fimg.jj20.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1644588215&t=9a40338757751be9d2684f0d3c80ae31',
                    width: 100.0,
                  ),
                ),
              ),
              onTap: () {
                //打开B路由
                Navigator.push(context, PageRouteBuilder(
                  pageBuilder: (
                      BuildContext context,
                      animation,
                      secondaryAnimation,
                      ) {
                    return FadeTransition(
                      opacity: animation,
                      child: Scaffold(
                        appBar: AppBar(
                          title: Text("原图"),
                        ),
                        body: HeroAnimationRouteB(),
                      ),
                    );
                  },
                ));
              },
            ),
            Padding(
              padding: const EdgeInsets.only(top: 8.0),
              child: Text("点击头像"),
            )
          ],
        ),
      ),
    );
  }
}


class HeroAnimationRouteB extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Hero(
        tag: "avatar", //唯一标记,前后两个路由页Hero的tag必须相同
        child: Image.network('https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.jj20.com%2Fup%2Fallimg%2F511%2F101611154647%2F111016154647-10-1200.jpg&refer=http%3A%2F%2Fimg.jj20.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1644588215&t=9a40338757751be9d2684f0d3c80ae31'),
      ),
    );
  }
}

效果渐变:

我们可以看到,实现 Hero 动画只需要用Hero组件将要共享的 widget 包装起来,并提供一个相同的 tag 即可,中间的过渡帧都是 Flutter 框架自动完成的。必须要注意, 前后路由页的共享Hero的 tag 必须是相同的,Flutter 框架内部正是通过 tag 来确定新旧路由页widget的对应关系的。

Hero 动画的原理比较简单,Flutter 框架知道新旧路由页中共享元素的位置和大小,所以根据这两个端点,在动画执行过程中求出过渡时的插值(中间态)即可,而感到幸运的是,这些事情不需要我们自己动手,Flutter 已经帮我们做了,有兴趣可以去看 Hero 动画相关的源码。

完整代码:flutter_demo: flutter组件测试学习demo

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Flutter 加载中动画是指在数据加载或处理过程中为用户提供的视觉反馈。在 Flutter 中,我们可以使用多种方法来实现加载中动画。 一种常见的方式是使用 Flutter 自带的 CircularProgressIndicator 组件。这是一个圆形进度指示器,可以显示加载进度的百分比。我们可以通过设置 value 属性来控制进度的大小,通常可以将它与 FutureBuilder 或 StreamBuilder 结合使用来显示网络请求或异步操作的进度。此外,我们还可以通过设置颜色和线条粗细等属性来自定义 CircularProgressIndicator 的外观。 除了 CircularProgressIndicator,Flutter 还提供了许多其他的加载中动画,比如 LinearProgressIndicator、RefreshIndicator 等。LinearProgressIndicator 是一个线性进度指示器,适用于表示长时间操作的进度。RefreshIndicator 则是下拉刷新的效果,用户在列表或页面顶部下拉时,会出现一个圈圈的加载动画,表示正在刷新数据。 除了使用预置的加载中动画组件,我们还可以通过自定义动画来实现更丰富的加载中效果。Flutter 提供了强大的动画库和组件,如 AnimatedContainer、AnimationController 等,使得创建自定义加载中动画变得更加方便。 总之,Flutter 提供了各种加载中动画的选择,无论是使用预置组件还是自定义动画,都可以根据项目需求和个人喜好来实现加载中效果。这些加载中动画可以提升用户体验,让用户在等待数据加载时感到更舒适和愉悦。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

风雨「83」

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

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

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

打赏作者

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

抵扣说明:

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

余额充值