Flutter中如何实现点击侧边栏触发的二级自定义菜单
Flutter 自定义带二级菜单的侧边栏实现方案
1. 定义菜单数据结构
先把主菜单和对应的二级菜单关联起来,创建数据模型类统一管理菜单信息:
class MenuItem { final IconData icon; final String title; final List<String>? subItems; // 二级菜单列表,为空则表示该主菜单无二级项 MenuItem({required this.icon, required this.title, this.subItems}); }
2. 更新状态变量
在_SideMenuState中添加状态变量,用于跟踪菜单的选中和展开状态:
final List<MenuItem> menuItems = [ MenuItem(icon: Icons.home, title: '首页'), MenuItem(icon: Icons.settings, title: '设置', subItems: ['账号设置', '通知设置', '隐私设置']), MenuItem(icon: Icons.dashboard, title: '仪表盘', subItems: ['数据概览', '统计报表']), // 根据需求添加更多菜单 ]; int? expandedIndex; // 记录当前展开的主菜单索引,null表示无展开菜单 late List<bool> selected; // 主菜单选中状态 @override void initState() { super.initState(); // 初始化选中状态,默认所有主菜单都未选中 selected = List.generate(menuItems.length, (index) => false); }
3. 修改菜单点击逻辑
更新select方法,同时处理主菜单选中切换和二级菜单的展开/收起:
void select(int index) { setState(() { // 重置所有主菜单的选中状态 for (int i = 0; i < selected.length; i++) { selected[i] = false; } selected[index] = true; // 切换二级菜单状态:点击当前展开的菜单则收起,否则展开(仅当该菜单有二级项时) if (expandedIndex == index) { expandedIndex = null; } else { expandedIndex = menuItems[index].subItems != null ? index : null; } }); }
4. 重构UI布局,添加二级菜单
修改build方法,在Stack中加入二级菜单容器,通过Positioned定位在主侧边栏右侧:
@override Widget build(BuildContext context) { return Stack( children: [ // 页面背景容器 Container(color: Colors.white), // 二级菜单:仅当有展开的菜单且该菜单存在二级项时显示 if (expandedIndex != null && menuItems[expandedIndex!].subItems != null) Positioned( left: 101.0, // 与主侧边栏宽度一致,保证对齐 top: 0, bottom: 0, child: AnimatedContainer( duration: const Duration(milliseconds: 300), width: 200.0, color: Colors.grey[100], child: ListView( padding: EdgeInsets.zero, children: menuItems[expandedIndex!].subItems! .map((subItem) => ListTile( title: Text(subItem), onTap: () { // 二级菜单点击逻辑,可根据需求添加选中状态 setState(() { // 示例:记录选中的二级菜单索引 // selectedSubIndex = ...; }); }, )) .toList(), ), ), ), // 主侧边栏容器 Container( height: MediaQuery.of(context).size.height, width: 101.0, decoration: const BoxDecoration( color: AppColors.mainBlueColor, ), child: ListView( padding: EdgeInsets.zero, children: List.generate( menuItems.length, (index) => Tooltip( message: menuItems[index].title, child: NavBarItem( icon: menuItems[index].icon, selected: selected[index], // 给有二级菜单的项添加箭头图标,提示展开状态 trailing: menuItems[index].subItems != null ? Icon( expandedIndex == index ? Icons.arrow_right : Icons.arrow_drop_down, color: Colors.white, ) : null, onTap: () => select(index), ), ), ), ), ), ], ); }
可选优化
- 可以给二级菜单的选中状态添加样式,比如背景色、文字颜色变化
- 给主侧边栏的箭头图标添加旋转动画,增强交互反馈
- 调整二级菜单的宽度、背景色等样式,匹配你的设计需求
内容的提问来源于stack exchange,提问作者Hashir Aslam
相关产品推荐
相关产品推荐

