Flutter Hero动画出现文本重复,求解决方法
解决Flutter Hero动画中文本重复的问题
这个问题的核心原因是你嵌套使用了Hero组件——在一个Hero内部又嵌套了另一个Hero,这会导致动画过程中两个文本元素同时显示,尤其是在放慢动画速度后,这种重复会变得格外明显。Hero的工作机制是将两个页面中相同tag的Widget提取到全局Overlay层进行过渡,嵌套Hero时,父Hero的过渡还未完成,子Hero的元素会同时存在于原页面、父Hero的过渡层以及子Hero自己的过渡层,最终造成文本重复显示。
解决方案:移除Hero的嵌套结构
我们可以把文本的过渡整合到主Hero(卡片)的动画中,不需要单独给文本套Hero。如果后续需要单独控制文本的动画细节,也可以让文本的Hero和主Hero处于同一层级,而非嵌套关系。下面是修改后的完整代码:
修改后的FirstPage布局
将文本从嵌套的Hero中移出,让它作为主Hero(卡片)的直接子元素:
@override Widget build(BuildContext context) { timeDilation = 10.0; return new Scaffold( appBar: new AppBar( title: new Text(widget.title), ), body: new Container( child: new ListView.builder( itemCount: palette.length, itemBuilder: (context, index) => new Hero( tag: palette[index].keys.first, child: new GestureDetector( onTap: () { Navigator.of(context).push(new ColorPageRoute(palette[index])); }, child: new Card( color: new Color(palette[index].values.first), child: new Align( alignment: Alignment.topRight, child: SizedBox( width: 250, child: new Text( palette[index].keys.first, style: Theme.of(context).textTheme.title.copyWith( color: Colors.white, ), ), ), ), ), ), ), ), ), ); }
修改后的SecondPage布局
同样让文本作为主Hero的直接子元素,移除单独的文本Hero:
@override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar( title: new Text('Color'), ), body: new Hero( tag: color.keys.first, child: new Container( color: new Color(color.values.first), child: new Align( child: new SizedBox( width: 200, child: new Text( color.keys.first, style: Theme.of(context).textTheme.title.copyWith(color: Colors.white), ), ), ), ), ), ); }
为什么这样能解决问题?
现在整个卡片(包含文本)作为一个整体进行Hero过渡,动画过程中只会有一个过渡元素在Overlay层显示,原页面的元素会被自动隐藏,不会出现重复的文本。
如果之后你需要对文本做更精细的独立动画(比如单独的缩放、位移控制),可以使用Hero的flightShuttleBuilder来自定义过渡过程,或者将文本和卡片拆分为两个独立的非嵌套Hero,但要确保两者的动画时序协调,避免再次出现重复显示的问题。
内容的提问来源于stack exchange,提问作者user2891729
相关产品推荐
相关产品推荐

