Flutter中如何用Hero组件实现Blob动画?动画效果异常求助
在Flutter中用Hero组件实现Blob动画的解决方案
可以实现,但默认Hero组件的过渡逻辑会导致Blob动画效果不佳——因为Hero默认会对源/目标组件生成静态快照,而Blob是持续动态的,过渡时快照无法保持动画连贯性。
解决方法
通过自定义Hero的flightShuttleBuilder,在过渡阶段维持Blob的动画状态,同时平滑过渡尺寸:
1. 源页面修改后的Hero代码
InkWell( onTap: () async { await Navigator.push( context, PageRouteBuilder( reverseTransitionDuration: Duration(milliseconds: 1500), transitionDuration: Duration(milliseconds: 1500), pageBuilder: (_, __, ___) => TechnologyAnimation(), ), ); }, child: Hero( tag: 'technology-animation', flightShuttleBuilder: ( BuildContext flightContext, Animation<double> animation, HeroFlightDirection flightDirection, BuildContext fromHeroContext, BuildContext toHeroContext, ) { // 根据过渡方向确定目标尺寸 final targetSize = flightDirection == HeroFlightDirection.push ? MediaQuery.of(toHeroContext).size.width * 0.8 // 目标页面Blob尺寸 : 300.0; // 源页面Blob尺寸 return AnimatedBuilder( animation: animation, builder: (context, child) { // 平滑过渡尺寸 final currentSize = Tween<double>( begin: 300.0, end: targetSize, ).animate(CurvedAnimation( parent: animation, curve: Curves.easeInOut )).value; return Blob.animatedFromID( loop: true, duration: Duration(milliseconds: 2500), size: currentSize, styles: BlobStyles(color: Colors.red), id: ['5-5-6092'], ); }, ); }, child: Container( child: Blob.animatedFromID( loop: true, duration: Duration(milliseconds: 2500), size: 300, styles: BlobStyles(color: Colors.red), id: ['5-5-6092'], ), ), ), )
2. 目标页面TechnologyAnimation中的Hero代码
Hero( tag: 'technology-animation', child: Container( child: Blob.animatedFromID( loop: true, duration: Duration(milliseconds: 2500), size: MediaQuery.of(context).size.width * 0.8, // 自定义目标尺寸 styles: BlobStyles(color: Colors.red), id: ['5-5-6092'], ), ), )
关键说明
flightShuttleBuilder替代了默认的快照逻辑,在过渡全程使用持续动画的Blob组件,保证形状动画不中断。- 源和目标Blob的核心动画参数(id、duration、loop、color)保持一致,仅调整尺寸,提升视觉连贯性。
- 可通过
CurvedAnimation添加过渡曲线,让尺寸变化更平滑自然。
内容的提问来源于stack exchange,提问作者Rohit Krishna
相关产品推荐
相关产品推荐

