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

Flutter中Navigator.push/pop失效,CircularProgressIndicator无法关闭

问题:Flutter注册功能中Navigator跳转与弹窗关闭失效导致界面卡死

注册流程中出现两个核心问题:

  • 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(),
          );
        });
  }

问题原因与解决方法

核心问题分析

  1. 上下文层级混乱:showDialog会在当前路由栈新增一个弹窗路由,原代码中Navigator.of(context).pop()是尝试关闭注册页面路由,而非弹窗路由;同时弹窗覆盖上下文后,Navigator.push的跳转操作无法正确触发。
  2. 异步操作未正确处理:showDialog是异步函数,原代码未等待其完成就执行后续逻辑,导致上下文状态异常。
  3. 未处理异常分支的弹窗关闭:仅在正常流程调用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 03:46:13