Flutter开发There are multiple heroes that share the same tag within a subtree报错

文章目录

    • 报错
    • 原因和解决方法
      • [为什么需要唯一的 `heroTag`?](#为什么需要唯一的 heroTag?)
      • [解决方案:为每个 FAB 分配唯一 `heroTag`](#解决方案:为每个 FAB 分配唯一 heroTag)
      • 注意事项

报错

报错内容

复制代码
======== Exception caught by scheduler library =====================================================
The following assertion was thrown during a scheduler callback:
There are multiple heroes that share the same tag within a subtree.

Within each subtree for which heroes are to be animated (i.e. a PageRoute subtree), each Hero must have a unique non-null tag.
In this case, multiple heroes had the following tag: <default FloatingActionButton tag>
Here is the subtree for one of the offending heroes: Hero
  tag: <default FloatingActionButton tag>
  state: _HeroState#08778
When the exception was thrown, this was the stack: 
#0      Hero._allHeroesFor.inviteHero.<anonymous closure> (package:flutter/src/widgets/heroes.dart:277:11)
#1      Hero._allHeroesFor.inviteHero (package:flutter/src/widgets/heroes.dart:288:8)
#2      Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:306:11)
#3      SingleChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:6744:14)
#4      Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#5      ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#6      Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#7      SingleChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:6744:14)
#8      Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#9      ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#10     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#11     SingleChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:6744:14)
#12     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#13     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#14     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#15     MultiChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:6856:16)
#16     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#17     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#18     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#19     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#20     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#21     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#22     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#23     MultiChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:6856:16)
#24     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#25     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#26     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#27     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#28     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#29     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#30     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#31     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#32     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#33     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#34     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#35     SingleChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:6744:14)
#36     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#37     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#38     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#39     SingleChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:6744:14)
#40     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#41     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#42     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#43     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#44     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#45     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#46     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#47     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#48     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#49     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#50     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#51     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#52     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#53     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#54     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#55     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#56     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#57     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#58     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#59     SingleChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:6744:14)
#60     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#61     SingleChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:6744:14)
#62     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#63     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#64     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#65     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#66     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#67     MultiChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:6856:16)
#68     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#69     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#70     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#71     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#72     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#73     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#74     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#75     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#76     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#77     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#78     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#79     MultiChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:6856:16)
#80     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#81     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#82     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#83     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#84     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#85     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#86     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#87     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#88     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#89     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#90     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#91     SingleChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:6744:14)
#92     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#93     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#94     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#95     SingleChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:6744:14)
#96     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#97     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#98     Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#99     ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#100    Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#101    ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#102    Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#103    ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#104    Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#105    ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#106    Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#107    ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#108    Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#109    ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#110    Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#111    ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#112    Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#113    ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#114    Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#115    SingleChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:6744:14)
#116    Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#117    ComponentElement.visitChildren (package:flutter/src/widgets/framework.dart:5532:14)
#118    Hero._allHeroesFor.visitor (package:flutter/src/widgets/heroes.dart:321:15)
#119    SingleChildRenderObjectElement.visitChildren (package:flutter/src/widgets/framework.dart:6744:14)
#120    Element.visitChildElements (package:flutter/src/widgets/framework.dart:3720:5)
#121    Hero._allHeroesFor (package:flutter/src/widgets/heroes.dart:324:13)
#122    HeroController._startHeroTransition (package:flutter/src/widgets/heroes.dart:959:14)
#123    HeroController._maybeStartHeroTransition.<anonymous closure> (package:flutter/src/widgets/heroes.dart:914:9)
#124    SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1386:15)
#125    SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1322:11)
#126    SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:1169:5)
#127    _invoke (dart:ui/hooks.dart:312:13)
#128    PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:399:5)
#129    _drawFrame (dart:ui/hooks.dart:283:31)

原因和解决方法

在 Flutter 中,当多个页面使用 FloatingActionButton(FAB)且希望实现 Hero 动画时,需要为每个 FAB 设置唯一的 heroTag,以避免导航时的冲突。以下是详细解释和解决方案:


为什么需要唯一的 heroTag

  1. Hero 动画机制

    Flutter 的 Hero 组件通过 tag 属性在页面跳转时关联两个相同 tag 的组件,实现共享元素动画。如果多个页面的 FAB 使用相同的 heroTag,Flutter 无法确定目标页面的 Hero 目标,导致冲突或动画异常。

  2. 默认行为的隐患

    如果未显式设置 heroTag,Flutter 会为每个 FAB 自动生成一个唯一的 tag。但显式设置可以避免意外冲突,尤其是当多个 FAB 存在于不同页面时。


解决方案:为每个 FAB 分配唯一 heroTag

  1. 显式设置 heroTag

    在每个页面的 FAB 外包裹 Hero 组件,并为 heroTag 指定唯一值(如页面名称 + FAB 功能)。

    dart 复制代码
    // 页面 A
    Hero(
      tag: 'fab_page_a',
      child: FloatingActionButton(
        onPressed: () { /* ... */ },
        child: Icon(Icons.add),
      ),
    )
    
    // 页面 B
    Hero(
      tag: 'fab_page_b',
      child: FloatingActionButton(
        onPressed: () { /* ... */ },
        child: Icon(Icons.edit),
      ),
    )
  2. 避免 Hero 动画

    如果不需要 Hero 动画,可以直接禁用 heroTag

    dart 复制代码
    FloatingActionButton(
      heroTag: null, // 禁用 Hero 动画
      onPressed: () { /* ... */ },
      child: Icon(Icons.add),
    )

注意事项

  • 唯一性原则
    确保 heroTag 在整个应用中唯一。可以通过页面路径、功能名称或 UUID 生成。
  • 性能优化
    Hero 动画涉及跨页面渲染,避免在复杂 UI 中过度使用,以免影响性能。
  • 测试验证
    在页面跳转时测试 Hero 动画的流畅性,确保无冲突或闪烁。

通过为每个 FAB 显式设置唯一的 heroTag,可以避免导航时的 Hero 冲突,同时保持 UI 的连贯性和用户体验。


结束语

Flutter是一个由Google开发的开源UI工具包,它可以让您在不同平台上创建高质量、美观的应用程序,而无需编写大量平台特定的代码。我将学习和深入研究Flutter的方方面面。从基础知识到高级技巧,从UI设计到性能优化,欢饮关注一起讨论学习,共同进入Flutter的精彩世界!

相关推荐
jiet_h16 分钟前
深入解析Kapt —— Kotlin Annotation Processing Tool 技术博客
android·开发语言·kotlin
朴拙数科32 分钟前
技术长期主义:用本分思维重构JavaScript逆向知识体系(一)Babel、AST、ES6+、ES5、浏览器环境、Node.js环境的关系和处理流程
javascript·重构·es6
alexhilton44 分钟前
实战:探索Jetpack Compose中的SearchBar
android·kotlin·android jetpack
拉不动的猪1 小时前
vue与react的简单问答
前端·javascript·面试
uhakadotcom2 小时前
EventBus:简化组件间通信的利器
android·java·github
小墙程序员2 小时前
Flutter 教程(十)主题
flutter
旭久2 小时前
react+antd封装一个可回车自定义option的select并且与某些内容相互禁用
前端·javascript·react.js
阿丽塔~2 小时前
React 函数组件间怎么进行通信?
前端·javascript·react.js
笑鸿的学习笔记2 小时前
ROS2笔记之服务通信和基于参数的服务通信区别
android·笔记·microsoft