如何在Flutter Desktop中使用GetX实现双层侧边栏?
用GetX实现Flutter Desktop双层联动侧边栏
直接上可行的实现方案,核心是利用GetX的响应式状态管理,让二级侧边栏跟随一级菜单的选中状态自动更新,不需要用PageView:
1. 定义菜单数据模型
先统一菜单的数据结构,方便后续管理:
class MenuItem { final String title; final List<MenuItem>? subMenus; MenuItem({required this.title, this.subMenus}); }
2. 创建GetX控制器
这个控制器负责维护选中的一级菜单索引,以及提供菜单数据和切换方法:
class SidebarController extends GetxController { // 选中的一级菜单索引,默认选中第一个 final selectedMainIndex = 0.obs; // 模拟菜单数据 final List<MenuItem> mainMenus = [ MenuItem( title: "Dashboard", subMenus: [ MenuItem(title: "概览"), MenuItem(title: "统计"), MenuItem(title: "报表"), ], ), MenuItem( title: "用户管理", subMenus: [ MenuItem(title: "用户列表"), MenuItem(title: "权限设置"), MenuItem(title: "角色管理"), ], ), MenuItem( title: "系统设置", subMenus: [ MenuItem(title: "基础配置"), MenuItem(title: "日志查看"), ], ), ]; // 切换一级菜单的方法 void switchMainMenu(int index) { selectedMainIndex.value = index; } // 获取当前选中的一级菜单的子菜单 List<MenuItem> get currentSubMenus { if (selectedMainIndex.value >= mainMenus.length) return []; return mainMenus[selectedMainIndex.value].subMenus ?? []; } }
3. 实现双层侧边栏UI
在主页面中初始化控制器,然后分别渲染一级和二级侧边栏,用Obx包裹二级侧边栏实现响应式更新:
class DoubleSidebarPage extends StatelessWidget { final SidebarController controller = Get.put(SidebarController()); DoubleSidebarPage({super.key}); @override Widget build(BuildContext context) { return Scaffold( body: Row( children: [ // 一级侧边栏 Container( width: 200, color: Colors.grey[900], child: ListView.builder( itemCount: controller.mainMenus.length, itemBuilder: (context, index) { final menu = controller.mainMenus[index]; return Obx(() => GestureDetector( onTap: () => controller.switchMainMenu(index), child: Container( padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 20), color: controller.selectedMainIndex.value == index ? Colors.blue[700] : null, child: Text( menu.title, style: TextStyle( color: Colors.white, fontSize: 16, fontWeight: controller.selectedMainIndex.value == index ? FontWeight.bold : FontWeight.normal, ), ), ), )); }, ), ), // 二级侧边栏 Container( width: 180, color: Colors.grey[800], child: Obx(() => ListView.builder( itemCount: controller.currentSubMenus.length, itemBuilder: (context, index) { final subMenu = controller.currentSubMenus[index]; return Container( padding: const EdgeInsets.symmetric(vertical: 14, horizontal: 24), child: Text( subMenu.title, style: const TextStyle(color: Colors.white70, fontSize: 14), ), ); }, )), ), // 主内容区域 Expanded( child: Container( color: Colors.white, alignment: Alignment.center, child: Obx(() => Text( "当前选中:${controller.mainMenus[controller.selectedMainIndex.value].title}", style: const TextStyle(fontSize: 20), )), ), ), ], ), ); } }
关键说明
- 用
selectedMainIndex.obs把索引变成响应式变量,当它变化时,所有用Obx包裹的UI都会自动更新 - 二级侧边栏直接通过
controller.currentSubMenus获取当前选中一级菜单的子菜单,不需要PageView,更简洁高效 - 一级菜单的选中状态也用
Obx包裹,点击时自动高亮
这样实现的双层侧边栏完全符合需求,点击一级菜单时二级菜单会实时更新,适配Flutter Desktop的场景。
内容的提问来源于stack exchange,提问作者Faisaldy
相关产品推荐
相关产品推荐

