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

Flutter迁移至go_router后,如何判断弹窗是否已显示?

解决GoRouter下判断加载弹窗是否存在并安全关闭的问题

从Navigator 1迁移到go_router后,原来通过ModalRoute.of(context)判断弹窗的方法失效,用canPop()又会误关页面,试试下面几个靠谱的解决方案:

方案1:用变量跟踪弹窗状态

在发起请求时,用一个布尔变量记录弹窗是否显示,请求完成后根据变量状态决定是否关闭:

bool _isLoadingShown = false;

void fetchData() async {
  _isLoadingShown = true;
  // 显示加载弹窗
  showDialog(
    context: context,
    barrierDismissible: false,
    builder: (_) => const Center(child: CircularProgressIndicator()),
  );

  try {
    // 执行HTTP请求
    await http.get(Uri.parse('你的接口地址'));
    // 处理响应
  } catch (e) {
    // 处理错误
  } finally {
    // 弹窗显示时才关闭
    if (_isLoadingShown) {
      Navigator.of(context).pop();
      _isLoadingShown = false;
    }
  }
}

这种方式简单直接,适合单个弹窗的场景,注意变量要和弹窗的生命周期绑定,避免内存泄漏。

方案2:用GlobalKey精准控制弹窗

给弹窗单独分配一个GlobalKey,通过这个Key来判断弹窗是否存在并关闭,不会影响页面路由:

GlobalKey<NavigatorState>? _dialogKey;

void showLoading() {
  showDialog(
    context: context,
    barrierDismissible: false,
    builder: (dialogCtx) {
      _dialogKey = GlobalKey<NavigatorState>();
      return Navigator(
        key: _dialogKey,
        onGenerateRoute: (_) => MaterialPageRoute(
          builder: (_) => const Center(child: CircularProgressIndicator()),
        ),
      );
    },
  );
}

void closeLoading() {
  if (_dialogKey?.currentState?.canPop() == true) {
    _dialogKey?.currentState?.pop();
    _dialogKey = null;
  }
}

调用时先执行showLoading(),请求完成后调用closeLoading(),只会关闭对应的弹窗,不会碰页面栈。

方案3:封装弹窗管理类

把弹窗的显示、关闭逻辑封装成单例类,内部维护状态,不用在每个页面重复写代码:

class LoadingManager {
  static final LoadingManager _instance = LoadingManager._();
  LoadingManager._();
  factory LoadingManager() => _instance;

  bool _isDialogActive = false;
  BuildContext? _dialogContext;

  void show(BuildContext context) {
    if (!_isDialogActive) {
      _isDialogActive = true;
      showDialog(
        context: context,
        barrierDismissible: false,
        builder: (ctx) {
          _dialogContext = ctx;
          return const Center(child: CircularProgressIndicator());
        },
      ).whenComplete(() {
        _isDialogActive = false;
        _dialogContext = null;
      });
    }
  }

  void hide() {
    if (_isDialogActive && _dialogContext != null) {
      Navigator.of(_dialogContext!).pop();
    }
  }
}

使用时非常方便:

// 显示弹窗
LoadingManager().show(context);

// 请求完成后关闭
LoadingManager().hide();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 20:40:17