Flutter中Navigator.push/pop失效,CircularProgressIndicator无法关闭
注册流程中出现两个核心问题:
Navigator.push无法跳转到目标UserHomePage页面Navigator.pop无法关闭弹出的CircularProgressIndicator,最终导致界面卡死
相关代码
导入代码
import 'package:file_name/products/widget_helper/register_ui_widget_functions.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import '../helper/user_registration_helper.dart'; import '../model/user_registration_model.dart'; import '../pages/home_page.dart';
注册核心逻辑代码(register_widgets.dart)
Future signUpUser(emailUserCtrlr, passwordUserCtrlr, repeatPasswordUserCtrlr, firstNameUserCtrlr, lastNameUserCtrlr, context) async { RegistrationUser.checkFieldValidation(emailUserCtrlr, passwordUserCtrlr, repeatPasswordUserCtrlr, firstNameUserCtrlr, lastNameUserCtrlr); RegistrationUser.confirmPassword( passwordUserCtrlr, repeatPasswordUserCtrlr); if (RegistrationUser.confirmPassword( passwordUserCtrlr, repeatPasswordUserCtrlr)) { // CricularProgressIndicator here... ReusableWidgets.showDialogCircularIndicator(context); try { await FirebaseAuth.instance.createUserWithEmailAndPassword( email: emailUserCtrlr.text.trim(), password: passwordUserCtrlr.text.trim()); FirestoreUserHelper.create(UserModel( firstName: firstNameUserCtrlr.text.trim(), lastName: lastNameUserCtrlr.text.trim(), userEmail: emailUserCtrlr.text.trim(), )); ToastRegisterUser.registeredSuccessfully(); // Navigator.push not working Navigator.push( context, MaterialPageRoute(builder: (context) => const UserHomePage()), ); } on FirebaseAuthException catch (e) { ToastRegisterUser.emailAlreadyRegistered(emailUserCtrlr); } // Navigator Pop not working Navigator.of(context).pop(); } }
加载弹窗复用函数
static showDialogCircularIndicator(BuildContext context) { return showDialog( context: context, builder: (BuildContext context) { return const Center( child: CircularProgressIndicator(), ); }); }
问题原因与解决方法
核心问题分析
- 上下文层级混乱:
showDialog会在当前路由栈新增一个弹窗路由,原代码中Navigator.of(context).pop()是尝试关闭注册页面路由,而非弹窗路由;同时弹窗覆盖上下文后,Navigator.push的跳转操作无法正确触发。 - 异步操作未正确处理:
showDialog是异步函数,原代码未等待其完成就执行后续逻辑,导致上下文状态异常。 - 未处理异常分支的弹窗关闭:仅在正常流程调用
pop,异常分支下弹窗会一直留存。
修复代码与步骤
1. 优化注册核心逻辑
Future signUpUser(emailUserCtrlr, passwordUserCtrlr, repeatPasswordUserCtrlr, firstNameUserCtrlr, lastNameUserCtrlr, BuildContext context) async { // 执行字段验证 RegistrationUser.checkFieldValidation(emailUserCtrlr, passwordUserCtrlr, repeatPasswordUserCtrlr, firstNameUserCtrlr, lastNameUserCtrlr); // 仅调用一次密码验证,避免重复执行 final isPasswordValid = RegistrationUser.confirmPassword( passwordUserCtrlr, repeatPasswordUserCtrlr); if (isPasswordValid) { // 等待弹窗加载完成 await ReusableWidgets.showDialogCircularIndicator(context); try { // 执行Firebase注册 await FirebaseAuth.instance.createUserWithEmailAndPassword( email: emailUserCtrlr.text.trim(), password: passwordUserCtrlr.text.trim()); // 等待用户数据写入完成(必须加await,否则会提前跳转) await FirestoreUserHelper.create(UserModel( firstName: firstNameUserCtrlr.text.trim(), lastName: lastNameUserCtrlr.text.trim(), userEmail: emailUserCtrlr.text.trim(), )); ToastRegisterUser.registeredSuccessfully(); // 先关闭弹窗(rootNavigator确保操作最上层路由) Navigator.of(context, rootNavigator: true).pop(); // 跳转首页并移除之前的所有路由,避免返回注册页 Navigator.pushAndRemoveUntil( context, MaterialPageRoute(builder: (context) => const UserHomePage()), (route) => false, ); } on FirebaseAuthException catch (e) { ToastRegisterUser.emailAlreadyRegistered(emailUserCtrlr); // 异常分支也要关闭弹窗 Navigator.of(context, rootNavigator: true).pop(); } } }
2. 优化弹窗函数
static Future<void> showDialogCircularIndicator(BuildContext context) { return showDialog( context: context, barrierDismissible: false, // 禁止用户点击空白关闭弹窗 builder: (BuildContext dialogContext) { return const Center( child: CircularProgressIndicator(), ); }, ); }
额外注意事项
- 确保
FirestoreUserHelper.create是异步函数并添加await,避免用户数据未写入就跳转首页; - 使用
Navigator.pushAndRemoveUntil替代push,符合注册完成后无法返回注册页的业务逻辑; - 移除重复的密码验证调用,提升代码性能。
内容的提问来源于stack exchange,提问作者flutternewbiee
相关产品推荐
相关产品推荐

