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

Flutter路由跳转新页面后无法访问Provider问题求助

这个问题我之前也碰到过,核心原因是你的Provider层级放错位置了!

看你的代码,ChangeNotifierProvider是放在MaterialApp的home属性里,但MaterialApp内部会自动创建一个Navigator,也就是说你的Provider是在这个Navigator的子树里。当你用Navigator.push打开Page2时,Page2是被这个Navigator管理的,它的上下文只能向上找到Navigator,而Navigator的上层并没有Provider,自然就找不到了。

下面给你几种靠谱的解决方案,按推荐程度排序:


方案1:把Provider提升到MaterialApp外面(最推荐)

直接把ChangeNotifierProvider包裹在MaterialApp外层,这样整个App的所有组件(包括Navigator管理的所有页面)都能访问到Provider。修改后的代码如下:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider( // 移到MaterialApp外面
      create: (context) => MyModel(),
      child: MaterialApp(
        title: 'Flutter Demo',
        home: MyHomePage()
      )
    );
  }
}

这样修改后,Page2里的Provider.of<MyModel>(context)就能正常找到实例了,完全不需要改动其他代码。


方案2:利用MaterialApp的builder属性调整层级

如果你不想把Provider放在最外层,也可以用MaterialApp的builder属性来让Navigator处于Provider的子树中:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      builder: (context, child) {
        return ChangeNotifierProvider(
          create: (context) => MyModel(),
          child: child,
        );
      },
      home: MyHomePage()
    );
  }
}

builder属性返回的Widget会包裹在MaterialApp的Navigator外面,所以Provider的层级就比Navigator高,所有通过Navigator打开的页面都能访问到。


方案3:在跳转时传递Provider实例(不推荐,耦合性高)

虽然不建议,但如果特殊场景下你不想调整Provider层级,可以在push的时候把MyModel实例传过去:

在MyHomePage的FloatingActionButton点击事件里修改:

onPressed: () {
  var myModel = Provider.of<MyModel>(context, listen: false);
  Navigator.of(context).push(
    PageRouteBuilder(
      pageBuilder: (context, animation, secondaryAnimation) => Page2(myModel: myModel),
    ),
  );
}

然后修改Page2的定义:

class Page2 extends StatelessWidget {
  final MyModel myModel;
  Page2({required this.myModel});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(myModel.b),
      ),
    );
  }
}

这种方式虽然能解决问题,但会让Page2和MyModel产生强耦合,违背了Provider的依赖注入思想,所以只适合临时救急,不推荐长期使用。


另外你提到的Navigator.of(context, rootNavigator: true).context没用,是因为rootNavigator还是MaterialApp创建的那个Navigator,它的上下文上层依然没有Provider,所以自然找不到。

内容的提问来源于stack exchange,提问作者user2233706

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 14:07:30