使用Flutter LocalHero时触发'!_debugDisposed': is not true异常求助
Flutter LocalHeroScope 触发
!_debugDisposed 断言异常的排查与解决 异常原因
这个断言失败的核心是:LocalHero的过渡动画尚未完成时,对应的RenderObject已被销毁。结合你的代码场景:
- 当
dialPad状态切换时,KeyPadCustom和RingDialPad会被直接替换,旧组件树中的LocalHero及其子组件会被立即标记为disposed,但LocalHeroScope设置的300ms动画仍在执行,动画逻辑尝试访问已释放的RenderObject,触发断言。 - 被
Transform.translate包裹的LocalHero,其布局依赖动态计算的offset,组件销毁后Transform的RenderObject也会被释放,进一步触发该异常。
解决方法
1. 延迟旧组件销毁,等待动画完成
使用AnimatedSwitcher包裹切换的组件,让旧组件在动画结束后再销毁,确保动画执行期间RenderObject始终有效:
LocalHeroScope( duration: const Duration(milliseconds: 300), createRectTween: (begin, end) => RectTween(begin: begin, end: end), curve: Curves.easeOut, child: Expanded( child: AnimatedSwitcher( duration: const Duration(milliseconds: 300), // 与LocalHeroScope的duration一致 child: dialPad ? const KeyPadCustom() : const RingDialPad(), ), ), )
2. 确保LocalHero的Tag唯一且清晰
给不同组件中的LocalHero添加区分标识,避免同数字的tag在切换时出现混淆:
// RingDialPad中的LocalHero tag: "local_hero_ring_${Constants.dialPadNumbers[i].toString()}", // KeyPadCustom中的LocalHero tag: "local_hero_keypad_${Constants.dialPadNumbers[columnIndex].toString()}",
3. 调整LocalHero与Transform的层级
将LocalHero放在Transform.translate的外层,确保动画的RenderObject生命周期更稳定:
LocalHero( tag: "local_hero_ring_${Constants.dialPadNumbers[i].toString()}", child: Transform.translate( offset: Offset.fromDirection((i + 1) * -pi / 6, numberRadiusFromCenter), child: RoundedNumber( number: Constants.dialPadNumbers[i].toString(), color: Colors.black, radius: Constants.dialNumberRadius, style: GoogleFonts.bebasNeue().copyWith( color: Colors.white, fontSize: 35, fontWeight: FontWeight.w400, ), ), ), )
4. 临时绕过debug断言(不推荐)
如果仅在debug模式下出现该异常,可临时禁用断言,但这只是绕过问题而非解决:
void main() { debugDisableAssertionErrors = true; runApp(const MyApp()); }
内容的提问来源于stack exchange,提问作者yash gupta
相关产品推荐
相关产品推荐

