Flutter中Navigator.pop时FloatingActionButton抛出Scaffold.geometryOf错误
问题分析
这个错误的核心是状态更新时机与Scaffold的布局/绘制阶段冲突:
- 点击2k按钮时,先调用
model.update()(通过Future.microtask延迟触发notifyListeners()),再执行Navigator.push跳转页面; - 点击1k按钮执行
Navigator.pop返回时,之前延迟的notifyListeners()刚好触发页面重建,此时Scaffold仍在处理导航的动画/布局流程,还未进入绘制阶段,却被要求访问仅在绘制阶段可用的geometryOf信息,最终抛出错误; - 加上你使用了
FloatingActionButtonLocation.centerDocked,Scaffold需要计算FAB与BottomAppBar的位置关系,这个过程对几何数据的依赖更敏感,进一步放大了时机冲突的问题。
解决方案
方案1:调整状态更新时机,避免在帧中间触发重建
将MyModel中的update方法里的Future.microtask替换为postFrameCallback,确保状态更新在当前帧绘制完成后再执行:
class MyModel extends ChangeNotifier { int count = 0; void update(){ count ++; // 等待当前帧绘制完成后再通知监听器 WidgetsBinding.instance.addPostFrameCallback((_) { notifyListeners(); }); } }
方案2:同步触发状态更新(更简洁的方式)
如果不需要延迟更新,直接去掉Future.microtask,同步调用notifyListeners():
class MyModel extends ChangeNotifier { int count = 0; void update(){ count ++; notifyListeners(); } }
方案3:延迟状态更新到导航完成后
如果必须在导航前后更新状态,可以将状态更新逻辑放在导航的then回调中,确保导航完成后再触发重建:
修改2k按钮的点击事件:
IconButton( icon: Icon(Icons.two_k), onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (context) => Home(), maintainState: true), ).then((_) { // 导航完成后再更新状态 model.update(); }); }, ),
验证效果
按照上述任意方案修改后,点击2k按钮跳转、再点击1k按钮返回,不会再触发Scaffold.geometryOf()相关错误,页面导航和状态更新均可正常执行。
内容的提问来源于stack exchange,提问作者Rodrigo Sousa
相关产品推荐
相关产品推荐

