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

Flutter中如何在didPopNext回调中忽略弹窗?

解决Flutter中didPopNext误触发弹窗场景的问题

问题原因

Flutter里的弹窗(Dialog、BottomSheet等)是通过Overlay实现的,不属于PageRoute类型。当弹窗弹出/关闭时,RouteAware的didPopNext会被触发,但此时GetX的路由栈并没有真正的页面跳转,导致你用Get.previousRoute和Get.currentRoute的判断逻辑失效。

解决方案

方案一:记录弹窗路由类型,跳过触发逻辑

在页面状态类中新增标记变量,在didPushNext时判断被push的路由是否为弹窗类型,didPopNext时根据标记决定是否执行checkInterstitial:

class _HomePageState extends State<HomePage>
    with RouteAware, WidgetsBindingObserver {
  final controller = Get.find<HomeUiStore>();
  bool _isClosingDialog = false; // 标记是否是弹窗关闭触发的回调

  @override
  void initState() {
    WidgetsBinding.instance.addObserver(this);
    super.initState();
  }

  @override
  void didChangeDependencies() {
    appRouteObserver.subscribe(this, ModalRoute.of(context) as PageRoute);
    super.didChangeDependencies();
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    appRouteObserver.unsubscribe(this);
    AdMobUtil.dispose();
    FirebaseMessagingStore.dispose();
    super.dispose();
  }

  @override
  void didPushNext() {
    controller.onboardingKey.currentState?.hide();
    SnackBarUtil.instance.closeCurrentSnackbar();
    // 判断当前push的路由是否为弹窗类路由
    final currentRoute = ModalRoute.of(context);
    if (currentRoute is DialogRoute || currentRoute is ModalBottomSheetRoute) {
      _isClosingDialog = true;
    } else {
      _isClosingDialog = false;
    }
  }

  @override
  void didPopNext() {
    // 仅在非弹窗关闭场景下调用插屏广告检查
    if (!_isClosingDialog) {
      controller.checkInterstitial();
    }
    // 其他逻辑不受影响
    controller.checkShowOnboarding();
    controller.checkShowAlertSnackbar();
    // 重置标记
    _isClosingDialog = false;
  }
}

方案二:自定义RouteObserver,仅监听PageRoute

创建只处理PageRoute的路由观察者,弹窗类路由不会触发回调:

class PageOnlyRouteObserver extends RouteObserver<PageRoute<dynamic>> {
  @override
  void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) {
    super.didPush(route, previousRoute);
    // 仅对PageRoute类型的路由进行订阅
    if (route is PageRoute) {
      subscribe(route);
    }
  }

  @override
  void didPop(Route<dynamic> route, Route<dynamic>? previousRoute) {
    super.didPop(route, previousRoute);
    if (route is PageRoute) {
      unsubscribe(route);
    }
  }
}

将原有的appRouteObserver替换为这个自定义观察者,即可跳过弹窗触发的didPopNext回调。

方案选择

方案一无需改动全局配置,仅在目标页面内处理逻辑,适合单一页面的需求;方案二更适合全局统一忽略弹窗路由的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 21:55:14