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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 21:04:55