本篇基于Flutter 3.16.4,Dart 3.2.3版本
Flutter 3.16.4 • channel stable • https://github.com/flutter/flutter.git
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中都是有这个概念,它字面意思是英雄动画,其实就是在路由跳转(页面切换)时提供了一种类似飞行的效果,使得页面切换过渡非常丝滑和流畅的视角效果,最常用的场景为小图查看大图,下面一起进入文章的了解下吧~
Flutter基建系列文章
Flutter基建 - Dart基础类型
Flutter基建 - Dart方法和类
Flutter基建 - 文本组件
Flutter基建 - 按钮全解析
Flutter基建 - 布局组件全面解析
Flutter基建 - 离不开的列表组件
Flutter基建 - 形影不离的State**Widget
Flutter基建 - 异步加载UI
Flutter基建 - 12种隐式动画小组件全解析
Flutter基建 - Hero动画有多英雄
我们就以点击小图然后跳转到大图界面为例,来看看Hero动画可以帮助我们实现什么样的效果。
我们先来实现一个列表界面,列表中每个item展示一个Image和Text,然后对Image做Hero动画由小图飞行至大图。
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所用。
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传入的参数:
写完列表界面之后,我们再来看看大图界面是如何实现的。
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,如果觉得本文对你有所帮助,帮忙关注、赞或者收藏三连一下,谢谢~