使用不包含MainBloc类型的Bloc的上下文调用的BlocProvider.of()

时间:2019-09-24 21:02:43

标签: flutter bloc

我有一个位于主要路线内的MainBloc,该路线的底部有一个带有多个子路线的应用栏,我希望同一个BLoC可以在所有五个子路线上运行,以便当其中一个改变状态时阻止其他人看到效果。

我尝试了this这样的问题,但它确实与我要寻找的问题相去甚远,我还尝试按照错误建议的方法进行操作,但没有成功,这是我得到的消息: / p>

This can happen if:
    1. The context you used comes from a widget above the BlocProvider.
    2. You used MultiBlocProvider and didn't explicity provide the BlocProvider types.

    Good: BlocProvider<MainBloc>(builder: (context) => MainBloc())
    Bad: BlocProvider(builder: (context) => MainBloc()).

主要路线:

@override
  Widget build(BuildContext context) {
    return MultiBlocProvider(
      providers: [
        BlocProvider<MainBloc>(
          builder: (BuildContext context) => MainBloc(),
        ),
        BlocProvider<OtherBloc>(
          builder: (BuildContext context) => OtherBloc(),
        ),
      ],
      child: /..., //here I have the bottom app bar with 5 buttons to navigate between sub-routes
);

其中一个子路由:

@override
  Widget build(BuildContext context) {
    final MainBloc bloc = BlocProvider.of<MainBloc>(context);
    return /...; //here I have the context of this sub-route.
}

从我在教程和文章中看到的内容来看,该代码应该可以工作,但是我似乎找不到为什么不可以。

2 个答案:

答案 0 :(得分:3)

问题在于,除非您在MaterialApp上方提供InheritedWidget,否则您将无法跨路由访问InheritedWidgets。我建议将新路线包装在BlocProvider.value中,以将现有的集团提供给新路线,例如:

        Navigator.of(context).push(
          MaterialPageRoute<MyPage>(
            builder: (_) {
              return BlocProvider.value(
                value: BlocProvider.of<MyBloc>(context),
                child: MyPage(),
              );
            },
          ),
        );

您可以在bloc documentation

中找到有关此信息的更多详细信息

答案 1 :(得分:1)

由于这个孩子的应用栏位于底部: child: /..., //here I have the bottom app bar 那么我认为MultiBlocProvider(..)不会包装使用此Bloc的应用程序的整个部分,我的建议是将“ MaterialApp”包装为“ MultiBlocProvider”。

return MultiBlocProvider(
   providers: [..],
   child: MaterialApp(..) // Set MaterialApp as the child of the MultiBlocProvider
  //..
)