как я могу решить проблему контекста blocProvider?

У меня есть кнопка отправки, но когда я нажимаю кнопку, появляется следующая ошибка:

BlocProvider.of () вызывается с контекстом, не содержащим CreatePostCubit.
Не удалось найти предка, начиная с контекста, переданного в BlocProvider.of (). Это может произойти, если используемый вами контекст исходит из виджета над BlocProvider. Используемый контекст: 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)
                            },
                          ),
                        ],
                      ),
                    ),
                  ),
                );
              });
        },
      ),
    ),
  );
}

person coldasspirit    schedule 14.04.2021    source источник


Ответы (3)


Ваш 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(
        ...
person Nuts    schedule 14.04.2021
comment
BlocProvider.of () вызывается с контекстом, не содержащим CreatePostCubit. это дает еще это - person coldasspirit; 15.04.2021
comment
@coldasspirit обновлен - person Nuts; 15.04.2021
comment
blocProvider не имеет свойства builder. - person coldasspirit; 15.04.2021
comment
Извините, я использую разные blocProviders, обновляя anwser - person Nuts; 15.04.2021

Используйте BlocProvider.of<CreatePostCubit>(context,listen:false) вместо BlocProvider.of<CreatePostCubit>(context) в кнопке отправки.

person Nishuthan S    schedule 15.04.2021
comment
BlocProvider.of () вызывается с контекстом, не содержащим CreatePostCubit. это дает еще это - person coldasspirit; 15.04.2021

Я думаю, проблема в том, что контекст в BlocProvider.of<CreatePostCubit>(context) относится к исходному контексту, у которого нет локтя, поэтому попробуйте переименовать контекст в sth иначе, например _context:

create: (_context) => CreatePostCubit(),

и при таком звонке

 BlocProvider.of<CreatePostCubit>(_context)
person Moaid ALRazhy    schedule 15.04.2021