我该如何解决 blocProvider 上下文问题?

how can i solve blocProvider context problem?

我有提交按钮,但是当我按下按钮时出现这个错误:

BlocProvider.of() called with a context that does not contain a CreatePostCubit.
No ancestor could be found starting from the context that was passed to BlocProvider.of(). This can happen if the context you used comes from a widget above the BlocProvider. The context used was: Builder

我想上下文混合了。我该如何解决这个错误?

我的代码:

Widget createPostButton(BuildContext context) {
  final TextEditingController _postTitleController = TextEditingController();

  final TextEditingController _postDetailsController = TextEditingController();
  final TextEditingController _priceController = TextEditingController();

  final _formKey = GlobalKey<FormState>(debugLabel: '_formKey');
  return BlocProvider<CreatePostCubit>(
    create: (context) => CreatePostCubit(),
      child: Padding(
      padding: const EdgeInsets.only(right: 13.0, bottom: 13.0),
      child: FloatingActionButton(
        child: FaIcon(FontAwesomeIcons.plus),
        onPressed: () {
          showDialog(
              context: context,
              barrierDismissible: false,
              builder: (context) {
                return AlertDialog(
                  content: Form(
                    key: _formKey,
                    child: SingleChildScrollView(
                      child: Column(
                        mainAxisSize: MainAxisSize.min,
                        children: <Widget>[
                          Padding(
                              padding: EdgeInsets.all(8.0),
                              child: TextFormField(
                                autocorrect: true,
                                controller: _postTitleController,
                                textCapitalization: TextCapitalization.words,
                                enableSuggestions: false,
                                validator: (value) {
                                  if (value.isEmpty || value.length <= 4) {
                                    return 'Please enter at least 4 characters';
                                  } else {
                                    return null;
                                  }
                                },
                                decoration:
                                    InputDecoration(labelText: 'Post Title'),
                              )),
                          Padding(
                              padding: EdgeInsets.all(8.0),
                              child: TextFormField(
                                controller: _postDetailsController,
                                autocorrect: true,
                                textCapitalization: TextCapitalization.words,
                                enableSuggestions: false,
                                validator: (value) {
                                  if (value.isEmpty || value.length <= 25) {
                                    return 'Please enter at least 25 characters';
                                  } else {
                                    return null;
                                  }
                                },
                                decoration: InputDecoration(
                                    labelText: 'Write a post details'),
                              )),
                          Padding(
                              padding: EdgeInsets.all(8.0),
                              child: TextFormField(
                                controller: _priceController,
                                enableSuggestions: false,
                                inputFormatters: <TextInputFormatter>[
                                  FilteringTextInputFormatter.digitsOnly
                                ],
                                keyboardType: TextInputType.number,
                                validator: (value) {
                                  if (value.isEmpty || value.length >= 4) {
                                    return 'Please enter a valid value';
                                  } else {
                                    return null;
                                  }
                                },
                                decoration:
                                    InputDecoration(labelText: 'Enter the Price'),
                              )),
                          OutlinedButton(
                            style: OutlinedButton.styleFrom(
                              primary: Colors.white,
                              backgroundColor: Colors.blue,
                            ),
                            child: Text("Submit"),
                            onPressed: () => {
                              BlocProvider.of<CreatePostCubit>(context)
                                  .createNewPost(
                                      postTitle: _postTitleController.text,
                                      postDetails: _postDetailsController.text,
                                      price: _priceController.text)
                            },
                          ),
                        ],
                      ),
                    ),
                  ),
                );
              });
        },
      ),
    ),
  );
}

您的 showDialog 生成器正在使用新上下文。构建器返回的小部件不与最初调用 showDialog 的位置共享上下文。

只需将构建器参数重命名为其他名称

          showDialog(
              context: context,
              barrierDismissible: false,
              builder: (dialog_context) { // instead of context
                return AlertDialog(
                ....

您还需要用构建器包装 BlocProvide 子项(以便它可以访问继承的 BlocProvider)

BlocProvider<CreatePostCubit>(
    create: (context) => CreatePostCubit(),
    child: Builder(
        builder: (BuildContext context) => Padding(
        ...

在提交按钮中使用 BlocProvider.of<CreatePostCubit>(context,listen:false) 而不是 BlocProvider.of<CreatePostCubit>(context)

我认为问题在于上下文 BlocProvider.of<CreatePostCubit>(context) 指的是没有 cubit 的原始上下文,所以尝试将上下文重命名为 _context 之类的其他内容:

create: (_context) => CreatePostCubit(),

当这样调用时

 BlocProvider.of<CreatePostCubit>(_context)