part of "./side_nav.dart"; class _SideBar extends StatefulWidget { /// 导航Id final int? navId; /// 菜单项集合 final List items; final VSideNavViewController controller; const _SideBar({ required this.controller, this.navId, required this.items, }); @override State createState() => _SideBarState(); } class _SideBarState extends State<_SideBar> { static const double _cellHegiht = 68.0; @override void initState() { WidgetsBinding.instance.addPostFrameCallback((timeStamp) { if (mounted) { widget.controller.titleChangedEvent.addListener(_onTitleChanged); } }); super.initState(); } @override void dispose() { widget.controller.titleChangedEvent.removeListener(_onTitleChanged); super.dispose(); } @override Widget build(BuildContext context) { return Scrollbar( thumbVisibility: true, child: ListView( padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 12), children: _buildChildren(context), ), ); } List _buildChildren(BuildContext context) { final children = []; final hasAnyIcon = widget.items.any((e) => e.icon != null); final divider = Divider( height: 1, color: Colors.grey.shade400, indent: hasAnyIcon ? 36 : 0, endIndent: 12, ); final count = widget.items.length; for (var i = 0; i < count; i++) { final item = widget.items[i]; if (item.shouldRearrage) { children.add(const SizedBox(height: 32)); } else if (i > 0) { children.add(divider); } final cell = _buildMenuCell(item); children.add(cell); } return children; } Widget _buildMenuCell(VSideNavMenuItem item) { final hasSection = item.title == widget.controller.currentTitle; final cell = Padding( padding: const EdgeInsets.symmetric(horizontal: 12), child: VListFormCell( height: _cellHegiht, leadingIcon: Container( alignment: Alignment.center, child: item.icon, ), leadingIconWidth: 36, label: item.title, onTap: () { _onItemTap(item, hasSection); }, ), ); if (hasSection) { return _buildSectionItem(cell); } else { return cell; } } Widget _buildSectionItem(Widget itemWidget) { return SizedBox( height: _cellHegiht, child: Stack( children: [ itemWidget, Positioned.fill( child: Container( decoration: BoxDecoration( borderRadius: GlobalStyles.borderRadius, color: Theme.of(context).primaryColor.withOpacity(.2), ), ), ), ], ), ); } void _onTitleChanged(_, String? e) { setState(() {}); } void _onItemTap(VSideNavMenuItem item, bool hasSection) { if (item.onTap != null) { item.onTap!.call(); return; } if (hasSection) { // 不可重复路由 return; } if (item.pageBuilder != null) { widget.controller.pageChangedEvent.emit(this, item.pageBuilder!); widget.controller.titleChangedEvent.emit(this, item.title); } if (item.route != null) { Get.offAllNamed(item.route!.name, id: widget.navId); } } }