打开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
相关产品推荐
相关产品推荐

