dart 在 Flutter 中重启(关闭并再次打开)后,对话框状态未发生变化

lc8prwob  于 2023-11-14  发布在  Flutter
关注(0)|答案(2)|浏览(165)

我在一个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);
  }
}


我面临的问题是,每当对话框关闭后再次打开时,它不会显示来自区块的最新数据。对话框只显示区块中以前的数据。有人能指出它吗?我在哪里犯了错误?

xmq68pz9

xmq68pz91#

你的对话框没有显示新数据的原因是因为你正在创建一个新的块示例,尽管你说你没有。

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

字符串
在某些情况下,BlocProvider可用于向小部件树的新部分提供现有的cubit。这在需要将现有的cubit提供给新路由时最常用。在这种情况下,BlocProvider不会自动关闭cubit,因为它没有创建它。
要不创建新示例,您需要使用BlocProvider.value

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


它不会创建一个新的示例,而是使用之前的示例并将其提供给子窗口小部件,并且在使用完它后不会关闭块。这对于对话框和导航来说很方便。

iibxawm4

iibxawm42#

我认为这是对话框有它自己的上下文,创建一个状态,你不能直接改变,因为它是在所有层的顶部,你必须重建整个对话框进行更改。但是,我有类似的问题,我解决了它的几个步骤,也许它可以帮助别人:
1.您必须从拥有BlocProvider的父小部件传递相同的块示例。
功能:

void _someFunction(YourBloc yourBloc){...}

字符串
家长:

_someFunction(BlocProvider.of<YourBloc>(context));


1.创建一个STATEFblog小部件(不是无状态的),你可以在其中进行更改,然后从函数中传递相同的块到它。你只需通过构造函数传递它,如下所示:
final YourBloc yourBloc;
1.在这个小部件中,使用Blocker和SetState方法来更新这个小部件中的UI。

BlocListener<YourBloc, YourState>(
          bloc: widget.yourBloc,
          listener: (context, state) {
            setState(() {});
          },
          child: Text(widget.yourBloc.state.showExampleValue),
        );

相关问题