Flutter中如何程序化打开OpenContainer?解决_debugLocked报错
解决OpenContainer条件触发打开时的
!_debugLocked断言错误 错误原因
你在closedBuilder中直接调用action.call()触发导航操作,但closedBuilder属于Widget构建阶段的回调,此时Flutter的Navigator处于锁定状态(_debugLocked为true),不允许修改导航栈,因此触发了断言失败的报错。
解决方案
不要在构建期间直接调用导航操作,而是通过WidgetsBinding.instance.addPostFrameCallback延迟执行,确保在当前帧构建完成后再触发OpenContainer的打开动作。同时需要重置触发条件,避免组件每次重建都重复执行打开操作。
修改后的代码示例
OpenContainer( useRootNavigator: true, closedShape: const CircleBorder(), closedColor: themePurple.withOpacity(0.9), transitionDuration: const Duration(milliseconds: 500), closedBuilder: (context, action) { if (widget.launchFromWidgetCommand == "add_todo") { // 延迟到当前帧构建完成后执行导航 WidgetsBinding.instance.addPostFrameCallback((_) { action.call(); // 这里建议通知父组件重置launchFromWidgetCommand,避免重复触发 // 比如在父组件中实现重置方法:widget.resetLaunchCommand(); }); } return FloatingActionButton( tooltip: "Add New Task", onPressed: () { action.call(); }, backgroundColor: themePurple.withOpacity(0.9), child: const Icon( Icons.add, size: 30, color: Color.fromARGB(255, 47, 15, 83), ), ); }, openBuilder: (context, action) { return InputModal( goBack: () => action.call(), addTodo: widget.createTodo, time: widget.time, timeType: widget.timeType, index: widget.index, ); }, ),
额外注意事项
- 必须重置
launchFromWidgetCommand的值(比如设为null或其他非触发值),否则每次组件重建(比如父组件状态变化)都会再次触发打开操作。 - 如果你的组件是StatefulWidget,也可以将条件判断逻辑移到
didUpdateWidget生命周期中处理,同样搭配addPostFrameCallback触发导航,效果一致。
内容的提问来源于stack exchange,提问作者Pro
相关产品推荐
相关产品推荐

