Flutter|Flutter Hero 实现共享元素转场动画

系列文章

  1. Flutter 旋转动画 — RotationTransition
  2. Flutter 平移动画 — 4种实现方式
  3. Flutter 淡入淡出与逐渐出现动画
  4. Flutter 尺寸缩放、形状、颜色、阴影变换动画
  5. Flutter 列表Item动画 — AnimatedList实现Item左进左出、淡入淡出
  6. Flutter Hero 实现共享元素转场动画

文章目录
  • 系列文章
  • 1 动画效果
  • 2 Hero介绍
  • 3 未使用Hero时的页面切换
  • 4 使用Hero实现的转场动画

1 动画效果
2 Hero介绍 Hero 是Flutter提供的一个可以实现子Widget在页面切换时带有飞行效果的Widget,可实现元素共享动画效果。
实现方式:在2个页面之间,都使用Hero包裹子控件并设置相关的tag标识即可。
注意:同一个页面中不能使用多个相同的Hero Tag
3 未使用Hero时的页面切换 列表页面
class ListPage extends StatefulWidget { const ListPage({Key? key}) : super(key: key); @override State> createState() => _ListPageState(); }class _ListPageState extends State { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('列表页'), centerTitle: true), body: GridView.count( crossAxisCount: 2, children: List.generate(10, _buildItem), ), ); }Widget _buildItem(int index) { return CupertinoButton( padding: EdgeInsets.zero, onPressed: () { Navigator.of(context).push( MaterialPageRoute(builder: (context) => DetailPage(index: index)), ); }, child: _buildImageWidget(index), ); }// 列表页的Image size是120 Widget _buildImageWidget(int index) { return const FlutterLogo(size: 120); } }

详情页面
class DetailPage extends StatefulWidget { final int index; const DetailPage({Key? key, required this.index}) : super(key: key); @override State> createState() => _DetailPageState(); }class _DetailPageState extends State { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('详情页'), centerTitle: true), body: SizedBox( width: double.infinity, child: Column( mainAxisSize: MainAxisSize.min, children: [ const SizedBox(height: 12), _buildImageWidget(widget.index), const SizedBox(height: 12), Text( ' ${widget.index} :登高(作者:杜甫)', style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 20), ), const SizedBox(height: 12), const Text( '风急天高猿啸哀,\n渚清沙白鸟飞回。\n无边落木萧萧下,\n不尽长江滚滚来。' '\n万里悲秋常作客,\n百年多病独登台。\n艰难苦恨繁霜鬓,\n潦倒新停浊酒杯。\n', textAlign: TextAlign.center, style: TextStyle(color: Colors.black, fontSize: 15), ), ], ), ), ); }// 详情页的Image size是250 Widget _buildImageWidget(int index) { return const FlutterLogo(size: 250); } }

效果图

4 使用Hero实现的转场动画 【Flutter|Flutter Hero 实现共享元素转场动画】实现Widget切换页面时飞到下一页的动画,使用Hero Widget包裹列表与详情页的图片Widget,并设置相同的tag即可。
修改 _buildImageWidget,使用Hero包裹FlutterLogo,并传入唯一的tag
列表页
// 列表页的Image size是120 Widget _buildImageWidget(int index) { // 同一页面的hero不能有多个相同tag return Hero( tag: 'hero_tag_$index', child: const FlutterLogo(size: 120), ); }

详情页
// 详情页的Image size是250 Widget _buildImageWidget(int index) { return Hero( tag: 'hero_tag_$index', child: const FlutterLogo(size: 250), ); }

动画效果

    推荐阅读