You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:13:52