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

Flutter BLoC中如何在无错误状态下执行Navigator.of(context).pop()?2FA应用表单验证与页面返回问题求助

解决方案:修复2FA应用的崩溃问题与表单验证逻辑

看起来你遇到了两个关联的问题:点击"add"按钮时应用崩溃,以及表单未验证通过就直接返回上一页的逻辑错误。让我帮你拆解问题并给出修复方案。

问题根源分析

  1. 崩溃原因:你当前的代码在发送Bloc事件后立即调用Navigator.of(context).pop(),这会直接销毁当前页面的上下文(context)。而BlocListener需要这个上下文来弹出AlertDialog,当上下文已经不存在时,就会引发崩溃。
  2. 逻辑错误:你没有等待Bloc完成表单验证,就直接执行了返回操作,导致不管表单是否为空,都会先回到上一页,再弹出错误弹窗,完全不符合预期流程。

修复步骤

1. 新增Bloc状态表示验证成功

首先需要在你的ManualInputBloc中添加一个新的状态,用来标识表单验证通过:

class ManualInputSuccess extends ManualInputState {}

2. 调整Bloc的事件处理逻辑

在Bloc的mapEventToState方法中,完成表单验证逻辑,根据验证结果发出对应的状态:

@override
Stream<ManualInputState> mapEventToState(ManualInputEvent event) async* {
  if (event is GetFormTextEvent) {
    // 核心验证逻辑:检查必填字段是否为空
    if (event.secretKey?.trim().isEmpty ?? true) {
      yield ManualInputError(
        alertDialogErrorTitle: tr('error-title'), // 替换为你的本地化文本
        alertDialogErrorContent: tr('secret-key-empty'),
      );
    } else if (event.accountName?.trim().isEmpty ?? true) {
      yield ManualInputError(
        alertDialogErrorTitle: tr('error-title'),
        alertDialogErrorContent: tr('account-name-empty'),
      );
    } else {
      // 验证通过:这里可以添加保存TOTP信息的逻辑
      yield ManualInputSuccess();
    }
  }
}

3. 修改页面中的BlocListener与按钮逻辑

将返回上一页的逻辑从按钮的onPressed中移除,交给BlocListener监听ManualInputSuccess状态时执行;仅当收到ManualInputError状态时才弹出错误弹窗:

// 替换原AppBar中的BlocListener代码
BlocListener<ManualInputBloc, ManualInputState>(
  listener: (context, state) {
    if (state is ManualInputError) {
      // 验证失败:显示错误弹窗,此时页面未被pop,context有效
      Platform.isAndroid
          ? CustomAlertDialog.showAndroidAlertDialog(
              context,
              state.alertDialogErrorTitle,
              state.alertDialogErrorContent,
            )
          : CustomAlertDialog.showIosAlertDialog(
              context,
              state.alertDialogErrorTitle,
              state.alertDialogErrorContent,
            );
    } else if (state is ManualInputSuccess) {
      // 验证成功:返回上一页
      Navigator.of(context).pop();
    }
  },
  child: TextButton(
    onPressed: () {
      final manualInputBloc = BlocProvider.of<ManualInputBloc>(context);
      manualInputBloc.add(
        GetFormTextEvent(
          secretKey,
          issuer,
          accountName,
          numberOfDigits,
          timeStep,
        ),
      );
      // 移除原有的Navigator.pop(),不再直接返回
    },
    child: Text('add').tr(),
  ),
)

修复后的效果

  • 当表单必填字段为空时:Bloc发出ManualInputError状态,弹窗显示错误信息,页面保持不动
  • 当表单填写完整时:Bloc发出ManualInputSuccess状态,自动返回上一页,不会出现崩溃
  • 上下文始终有效,彻底解决了弹窗时的崩溃问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 10:37:45