Flutter应用登录成功后Navigator.push跳转失效问题
问题根因
登录后跳转失效是路由执行顺序错误导致的:
- 你把关闭加载弹窗的
Navigator.of(context).pop()写在了if/else逻辑块的最外层,不管登录成功还是失败都会执行这行代码。 - 当接口返回200时,代码执行顺序是:弹出登录成功toast → push进入NavbarScreen → 执行最后那行pop操作。此时路由栈最顶层是刚跳转的NavbarScreen,这行pop会直接把刚推入的NavbarScreen弹出销毁,视觉上就表现为跳转完全没生效,始终停留在登录页。
- 额外隐患:弹加载框时没有单独持有弹窗上下文,直接用页面根context执行pop,很容易出现误关页面、context失活报错的问题。
修复步骤
- 调整代码执行顺序:先关闭加载弹窗,再执行登录结果分支逻辑,不要把关闭弹窗的代码放在分支判断外面。
- 弹加载框时单独持有弹窗的BuildContext,确保pop操作只会关闭加载弹窗,不会影响正常路由栈。
- 登录成功场景建议使用
pushReplacement替代普通push,替换当前登录页路由,避免用户按返回键退回登录页。
修正后的核心登录代码
Future doLogin() async { WidgetsBinding.instance.focusManager.primaryFocus?.unfocus(); if(txtUsername.text.isEmpty || txtPassword.text.isEmpty) { showToast('email/password kosong'); return; } // 单独持有加载弹窗的上下文 BuildContext? loadingDialogContext; // 弹出加载框 showDialog( context: context, barrierDismissible: false, builder: (dialogContext) { loadingDialogContext = dialogContext; return const Center( child: CircularProgressIndicator(), ); }); final response = await http.post( Uri.parse('http://10.0.2.2/flutter/api/login'), body: {'email': txtUsername.text, 'password': txtPassword.text}, headers: {'Accept': 'application/json'} ); // 接口返回后先关闭加载弹窗,做安全校验避免context失活报错 if(loadingDialogContext != null && Navigator.canPop(loadingDialogContext!)){ Navigator.pop(loadingDialogContext!); } final responseData = json.decode(response.body); if (response.statusCode == 200) { showToast('berhasil login'); // 关闭弹窗后再执行跳转,用pushReplacement替换登录路由 Navigator.pushReplacement( context, MaterialPageRoute( builder: (BuildContext context) => const NavbarScreen(), )); } else { showToast('gagal login'); } }
额外优化建议
你在main.dart中已经配置了命名路由,登录跳转时也可以直接用命名路由写法,和全局路由配置保持统一:
Navigator.pushReplacementNamed(context, NavbarScreen.routeName);
内容的提问来源于stack exchange,提问作者Damara Jati P
相关产品推荐
相关产品推荐

