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

打开Cupertino模态底部弹窗时隐藏底部导航栏的问题

问题:CupertinoTabView中打开modal_bottom_sheet弹窗时底部导航栏不隐藏的解决办法

我使用modal_bottom_sheet库展示Cupertino模态弹窗,在带有CupertinoTabView的页面打开弹窗时,底部导航栏不会隐藏;若设置useRootNavigator: true,弹窗显示效果又不符合需求。


调用ModalBottomSheet的代码

onTap: () {
  showCupertinoModalBottomSheet<Widget>(
    useRootNavigator: true,
    expand: true,
    context: context,
    backgroundColor: Colors.transparent,
    builder: (context) => SupportHelpster(),
  );
},

底部导航栏代码

tabBuilder: (context, index) => CupertinoTabView(
      onGenerateRoute: (_) {
        switch (index) {
          case 0:
            return MaterialWithModalsPageRoute<Widget>(
              builder: (_) => const HomeScreen(),
            );
          case 1:
            return MaterialWithModalsPageRoute<Widget>(
              builder: (_) => const DocumentScreen(),
            );
          case 2:
            return MaterialWithModalsPageRoute<Widget>(
              builder: (_) => const ProfileScreen(),
            );
        }
      },
    ),

onGenerateRoute代码

Route? onGenerateRoute(RouteSettings settings) {
switch (settings.name) {
  case Screens.main:
    return CupertinoPageRoute<Widget>(
      builder: (_) => const CupertinoTabScreen(),
    );
  case Screens.home:
    return MaterialWithModalsPageRoute<Widget>(
      builder: (_) => const HomeScreen(),
    );
  case Screens.document:
    return MaterialWithModalsPageRoute<Widget>(
      builder: (_) => const DocumentScreen(),
    );
  case Screens.profile:
    return MaterialWithModalsPageRoute<Widget>(
      builder: (_) => const ProfileScreen(),
    );
  case Screens.details:
    return MaterialWithModalsPageRoute<Widget>(
      builder: (_) => const DetailsScreen(),
    );
  case Screens.hospital:
    return MaterialWithModalsPageRoute<Widget>(
      builder: (_) => const HospitalScreen(),
    );
  case Screens.profileSettings:
    return MaterialWithModalsPageRoute<Widget>(
      builder: (_) => const ProfileSettings(),
    );
  default:
    return CupertinoPageRoute<Widget>(
      builder: (_) => const NotFoundScreen(),
    );
}

解决方案

问题根源在于CupertinoTabView内部维护了独立的导航栈,默认调用弹窗时用的是TabView内的上下文,导致弹窗无法覆盖底部导航栏;而useRootNavigator: true会让弹窗挂载到根导航栈,打破原页面层级关系。

方案1:使用根导航上下文调用弹窗

通过Navigator.of(context, rootNavigator: true)获取根导航的上下文,用这个上下文调用弹窗,同时关闭useRootNavigator:

onTap: () {
  final rootContext = Navigator.of(context, rootNavigator: true).context;
  showCupertinoModalBottomSheet<Widget>(
    useRootNavigator: false,
    expand: true,
    context: rootContext,
    backgroundColor: Colors.transparent,
    builder: (context) => SupportHelpster(),
  );
},

方案2:统一TabView内的路由类型

把MaterialWithModalsPageRoute替换为CupertinoPageRoute,让TabView内的导航栈和根导航栈层级兼容:

tabBuilder: (context, index) => CupertinoTabView(
      onGenerateRoute: (_) {
        switch (index) {
          case 0:
            return CupertinoPageRoute<Widget>(
              builder: (_) => const HomeScreen(),
            );
          case 1:
            return CupertinoPageRoute<Widget>(
              builder: (_) => const DocumentScreen(),
            );
          case 2:
            return CupertinoPageRoute<Widget>(
              builder: (_) => const ProfileScreen(),
            );
        }
      },
    ),

方案3:调整弹窗布局约束

保持useRootNavigator: true,通过MediaQuery.removePadding移除弹窗底部的内边距,修正显示效果:

onTap: () {
  showCupertinoModalBottomSheet<Widget>(
    useRootNavigator: true,
    expand: true,
    context: context,
    backgroundColor: Colors.transparent,
    builder: (context) => MediaQuery.removePadding(
      context: context,
      removeBottom: true,
      child: SupportHelpster(),
    ),
  );
},

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 21:03:43