Flutter BLoC中如何在无错误状态下执行Navigator.of(context).pop()?2FA应用表单验证与页面返回问题求助
解决方案:修复2FA应用的崩溃问题与表单验证逻辑
看起来你遇到了两个关联的问题:点击"add"按钮时应用崩溃,以及表单未验证通过就直接返回上一页的逻辑错误。让我帮你拆解问题并给出修复方案。
问题根源分析
- 崩溃原因:你当前的代码在发送Bloc事件后立即调用
Navigator.of(context).pop(),这会直接销毁当前页面的上下文(context)。而BlocListener需要这个上下文来弹出AlertDialog,当上下文已经不存在时,就会引发崩溃。 - 逻辑错误:你没有等待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
相关产品推荐
相关产品推荐

