Состояние диалога не меняется после перезапуска (закрытия и повторного открытия) во флаттере

Я определил одну кнопку внутри одного StatelessWidget (у него будет логика создания блока и внедрение с использованием поставщика блока), при нажатии кнопки я показываю диалоговое окно и передаю ему экземпляр блока, как показано в коде.


//EsignBloc is defined here in parent statelessWidget. Defined i.e. creating the bloc instance and passing through the BlocProvider. Removed the code for simplicity


//This listener will be called when Button defined inside statelessWidget will be clicked. this is responsible for showing the dialog.
void _onClickHere(
    BuildContext context,
  ) {
    final dialog = Dialog(
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(AppConstants.borderRadius),
      ),
      elevation: 0.0,
      backgroundColor: Colors.transparent,
      child: _GetSignUsingOtpView(),
    );

    showDialog(
      context: context,
      builder: (_) => BlocProvider<EsignBloc>(
        create: (_) => BlocProvider.of<EsignBloc>(context), // passing already created bloc to dialog
        child: WillPopScope(
          onWillPop: () => Future.value(false),
          child: dialog,
        ),
      ),
      barrierDismissible: false,
    );
  }

Вставка кода _GetSignUsingOtpView ()

class _GetSignUsingOtpView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return BlocBuilder<EsignBloc, EsignState>(builder: (context, state) {
      return Container(
        decoration: BoxDecoration(
          color: AppColor.white,
          borderRadius: BorderRadius.circular(
            AppConstants.borderRadius,
          ),
        ),
        child: Column(
              mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                Align(
                  alignment: Alignment.centerRight,
                  child: InkWell(
                    onTap: () => _closeDialog(context),
                    child: Padding(
                      padding: const EdgeInsets.only(top: 8.0, right: 8),
                      child: Icon(
                        Icons.cancel,
                        color: AppColor.primaryDark,
                        size: SizeConfig.safeBlockVertical * 2,
                      ),
                    ),
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.all(24),
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    crossAxisAlignment: CrossAxisAlignment.stretch,
                    children: [
                      PrimaryText(text: state.otp), // data does not change after closing and opeing dialog again 
                      PrimaryText(text: state.remainingTime), // data does not change after closing and opeing dialog again 
                    ],
                  ),
                ),
              ],
            ),
      );
    });
  }

  void _closeDialog(BuildContext context) {
    Navigator.pop(context);
  }
}

Проблема, с которой я сталкиваюсь, заключается в том, что всякий раз, когда диалоговое окно открывается снова после закрытия, в нем не отображаются последние данные из блока. В диалоговом окне просто отображаются все предыдущие данные в блоке. Может кто-нибудь указать, где я делаю ошибку?


person Siddharth Chandra    schedule 19.12.2020    source источник
comment
Добавьте код для своего EsignState класса, возможно, вы пропустили замену props для Equatable.   -  person Tim Klingeleers    schedule 20.12.2020
comment
Я использую замороженную аннотацию для создания кода для EsignState   -  person Siddharth Chandra    schedule 20.12.2020


Ответы (1)


Причина, по которой в вашем диалоговом окне не отображаются новые данные, заключается в том, что вы создаете новый экземпляр блока. Даже если вы говорите, что это не так.

BlocProvider<EsignBloc>(
  create: (_) => BlocProvider.of<EsignBloc>(context), // passing already created bloc to dialog
  child: ...

В некоторых случаях BlocProvider может использоваться для предоставления существующего локтя новой части дерева виджетов. Это будет чаще всего использоваться, когда существующий локоть необходимо сделать доступным для нового маршрута. В этом случае BlocProvider не закроет локоть автоматически, поскольку он не создавал его.

Чтобы не создавать новый экземпляр, вам нужно использовать BlocProvider.value. Подробнее об этом можно узнать здесь

BlocProvider.value(
  value: BlocProvider.of<EsignBloc>(context),
  child: ...,
);

Вместо создания нового экземпляра он будет использовать предыдущий экземпляр и предоставить его дочернему виджету и НЕ закроет блок, когда он будет использовать его. Это удобно для диалогов и навигации.

person mrgnhnt96    schedule 11.01.2021