Flutter:移动端特定页面隐藏底部导航栏同时桌面端保留侧边栏的最优实现方案咨询
Flutter:移动端特定页面隐藏底部导航栏同时桌面端保留侧边栏的最优实现方案咨询
大家好,我正在开发一款覆盖iOS、Android、Web以及Windows/Mac桌面端的Flutter跨端应用,用的是Flutter 3.x + auto_route ^7.8.0。在做响应式导航的时候遇到了个棘手的问题,想请教下社区里的最佳实践方案。
先给大家展示下我的当前实现:
当前实现结构
带导航的主壳组件
class MainShell extends StatelessWidget { final Widget child; @override Widget build(BuildContext context) { final isMobile = MediaQuery.of(context).size.width < 768; return Scaffold( body: Row( children: [ if (!isMobile) NavigationSidebar(), // 桌面端固定显示侧边栏 Expanded(child: child), ], ), bottomNavigationBar: isMobile ? BottomNavigationBar(...) // 移动端显示底部导航 : null, ); } }
AutoRoute路由结构
@MaterialAutoRouter( routes: <AutoRoute>[ AutoRoute( path: '/', page: MainShell, children: [ AutoRoute(path: 'home', page: HomePage), AutoRoute(path: 'missions', page: MissionsPage), AutoRoute(path: 'form/:id', page: FormPage), // ← 就是这个页面出问题 ], ), ], )
具体问题
当用户跳转到*FormPage*时:
- 移动端:我希望隐藏底部导航栏,最大化屏幕可用空间(尤其是键盘弹出后,空间会更紧张)
- 桌面端:因为屏幕空间充足,我希望侧边栏保持可见,方便用户随时切换其他页面
但现在FormPage是嵌套在MainShell下的子路由,所以不管是移动端还是桌面端,导航组件(底部栏/侧边栏)都会一直显示,完全不符合我的需求。
我自己脑补了几个可能的解决方向,但拿不准哪个是最可维护、最符合Flutter最佳实践的,或者有没有更优的方案:
备选方案思考
- A. 为移动端和桌面端分别设计不同的路由结构?
- B. 给
MainShell传递一个标记参数,让它根据参数控制导航的显示/隐藏? - C. 完全重构现有的导航架构?
- D. 其他我没想到的方案?
我想要的是一个可维护的方案,不想为了控制导航可见性就去复制页面,也不想为此引入复杂的状态管理逻辑。
另外我也尝试过两个思路,但都有明显问题:
- 在
MainShell里做条件渲染:但父组件没办法感知当前激活的子页面是哪一个,没法针对性隐藏导航 - 把
FormPage移到MainShell的路由层级之外:但这样桌面端的侧边栏也会跟着消失,违背了桌面端的需求
有没有用过auto_route做过类似跨端导航的大佬能给点建议?最好是贴合当前技术栈的方案,万分感谢!
内容来源于stack exchange




