系列文章
- Flutter 旋转动画 — RotationTransition
- Flutter 平移动画 — 4种实现方式
- Flutter 淡入淡出与逐渐出现动画
- Flutter 尺寸缩放、形状、颜色、阴影变换动画
- Flutter 列表Item动画 — AnimatedList实现Item左进左出、淡入淡出
- Flutter Hero 实现共享元素转场动画
- Flutter Hero 实现径向变换动画 — 圆形变成矩形的转场动画
- Flutter 自定义动画 — 数字递增动画和文字逐行逐字出现或消失动画
文章目录
- 系列文章
- 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);@overrideState<StatefulWidget> createState() => _ListPageState();
}class _ListPageState extends State<ListPage> {@overrideWidget 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是120Widget _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);@overrideState<StatefulWidget> createState() => _DetailPageState();
}class _DetailPageState extends State<DetailPage> {@overrideWidget 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是250Widget _buildImageWidget(int index) {return const FlutterLogo(size: 250);}
}
效果图
4 使用Hero实现的转场动画
实现Widget切换页面时飞到下一页的动画,使用Hero Widget包裹列表与详情页的图片Widget,并设置相同的tag即可。
修改 _buildImageWidget,使用Hero包裹FlutterLogo,并传入唯一的tag
。
列表页
// 列表页的Image size是120Widget _buildImageWidget(int index) {// 同一页面的hero不能有多个相同tagreturn Hero(tag: 'hero_tag_$index',child: const FlutterLogo(size: 120),);}
详情页
// 详情页的Image size是250Widget _buildImageWidget(int index) {return Hero(tag: 'hero_tag_$index',child: const FlutterLogo(size: 250),);}
动画效果