You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter对话框重启后Bloc状态未更新问题排查

问题分析与解决方案

你的问题出在两个关键细节上,咱们一步步拆解清楚:

1. 提前创建对话框实例导致复用旧Widget

你在调用showDialog之前就提前创建了dialog变量:

final dialog = Dialog(
  shape: RoundedRectangleBorder(...),
  child: _GetSignUsingOtpView(),
);

然后在showDialog的builder回调里直接复用这个已经创建好的dialog实例。这意味着_GetSignUsingOtpView的build方法只会在第一次创建对话框时执行一次,后续再次打开对话框时,复用的是同一个Widget实例——它的BlocBuilder不会重新监听Bloc的最新状态,自然就一直显示旧数据了。

2. 使用错误的BlocProvider构造函数传递已有实例

你用BlocProvider.create来返回已经存在的Bloc实例:

BlocProvider<EsignBloc>(
  create: (_) => BlocProvider.of<EsignBloc>(context),
  ...
)

create构造函数的设计目的是创建新的Bloc实例,传递已有的实例应该用BlocProvider.value,这样不仅语义更准确,还能避免一些和Widget生命周期相关的潜在问题。


修正后的代码

调整对话框创建时机与Bloc传递方式

把dialog的创建逻辑移到showDialog的builder内部,同时改用BlocProvider.value传递已有Bloc:

void _onClickHere(BuildContext context) {
  showDialog(
    context: context,
    builder: (_) => BlocProvider.value(
      value: BlocProvider.of<EsignBloc>(context), // 用value传递已有Bloc实例
      child: WillPopScope(
        onWillPop: () => Future.value(false),
        // 每次打开对话框都重新创建Dialog和_GetSignUsingOtpView
        child: Dialog(
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(AppConstants.borderRadius),
          ),
          elevation: 0.0,
          backgroundColor: Colors.transparent,
          child: _GetSignUsingOtpView(),
        ),
      ),
    ),
    barrierDismissible: false,
  );
}

_GetSignUsingOtpView无需修改

你的_GetSignUsingOtpView里的BlocBuilder逻辑是正常的,只要Widget能重新构建,它就会自动读取Bloc的最新状态并更新UI。


这样修改后,每次打开对话框时都会重新创建_GetSignUsingOtpView实例,BlocBuilder会重新监听Bloc的当前状态,自然就能显示最新的数据了。

内容的提问来源于stack exchange,提问作者Purushotam Kumar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:02:25