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

问题描述

我正在从第一屏幕导航到第二屏幕。我在第二个屏幕中使用Bloc Pattern。我收到以下错误

 BlocProvider.of() called with a context that does not contain a Bloc of type 
   No ancestor Could be found starting from the context that was passed to BlocProvider.of<MyBloc>().

    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.

下面是我的导航代码

 BlocProvider<MyBloc>(
            create: (context) => MyBloc());
        Navigator.push(context,MaterialPageRoute(builder: (context) {
          
          return SecondScreen(context);
        }));

下面是我的SecondScreen类

  class SecondScreen extends StatefulWidget {
  @override
  _SecondScreenState createState() => _SecondScreenState();
   }

class _SecondScreenState extends State<SecondScreen> {
  MyBloc myBloc;

  @override
  void initState() {
    super.initState();
    myBloc = BlocProvider.of<MyBloc>(context);
    myBloc.add(FetchEvents());
 }

  @override
  Widget build(BuildContext context) {
  return MaterialApp(
  home: Builder(
    builder: (context) {
      return Material(
        child: Scaffold(
          appBar: AppBar(
            title: Text("New Screen"),actions: <Widget>[
              IconButton(
                icon: Icon(Icons.refresh),onpressed: () {
                  myBloc.add(FetchEvents());
                },),IconButton(
                icon: Icon(Icons.info),onpressed: () {
                },)
            ],body: Container(
            child: BlocListener<MyBloc,MyState>(
              listener: (context,state) {
                if (state is MyErrorState) {
                  Scaffold.of(context).showSnackBar(
                    SnackBar(
                      content: Text(state.message),);
                }
              },child: BlocBuilder<MyBloc,MyState>(
                builder: (context,state) {
                  if (state is MyInitialState) {
                    return buildLoading();
                  } else if (state is MyLoadingState) {
                    return buildLoading();
                  } else if (state is MyLoadedState) {
                    return buildArticleList(state.yList);
                  } else if (state is MyErrorState) {
                    return buildErrorUi(state.message);
                  }
                },);
    },);
   }

 Widget buildLoading() {
  return Center(
  child: CircularProgressIndicator(),);
 }

  Widget buildErrorUi(String message) {
 return Center(
  child: Padding(
    padding: const EdgeInsets.all(8.0),child: Text(
      message,style: TextStyle(color: Colors.red),);
 }

  Widget buildArticleList(List<Data> data) {
  return ListView.builder(
  itemCount: data.length,itemBuilder: (ctx,pos) {
    return Padding(
      padding: const EdgeInsets.all(8.0),child: InkWell(
        child: ListTile(
         
          title: Text(data[pos].title),subtitle: Text(data[pos].shortDesc),onTap: () {
          // navigatetoArticleDetailPage(context,articles[pos]);
        },);
  },);
  }
 }

我刚刚开始学习集团并停留在这里。任何人都可以帮忙。

我没有在main.dart中添加任何与bloc相关的内容。需要吗?

解决方法

问题出在这部分:

 BlocProvider<MyBloc>(
            create: (context) => MyBloc());
        Navigator.push(context,MaterialPageRoute(builder: (context) {
          
          return SecondScreen(context);
        }));

对此进行更改可能会解决该问题:

 BlocProvider<MyBloc>(
            create: (context) => MyBloc());
        Navigator.push(context,MaterialPageRoute(
          builder: (routeContext) => SecondScreen(),}));
,

将已使用的 widget 包裹在 BlocProvider 内,这将提供要使用的正确上下文。

BlocProvider(
      create: (BuildContext context) {
          return _yourBloc;
      },child: Widget(