如何在Flutter Web中实现鼠标悬停弹出PopupMenu菜单?
完全可行,默认的PopupMenuButton是点击触发,咱们可以通过MouseRegion监听鼠标的进入/离开事件,手动控制菜单的显示与隐藏。
下面是修改后的完整实现代码:
class HoverPopupMenu extends StatefulWidget { const HoverPopupMenu({super.key}); @override State<HoverPopupMenu> createState() => _HoverPopupMenuState(); } class _HoverPopupMenuState extends State<HoverPopupMenu> { // 记录菜单是否显示 bool _isMenuOpen = false; // 用于获取按钮位置的全局key final GlobalKey _menuKey = GlobalKey(); // 显示菜单 void _showMenu() { if (_isMenuOpen) return; setState(() => _isMenuOpen = true); // 获取按钮的屏幕位置,确定菜单弹出的位置 final RenderBox button = _menuKey.currentContext!.findRenderObject() as RenderBox; final RenderBox overlay = Overlay.of(context).context.findRenderObject() as RenderBox; final RelativeRect position = RelativeRect.fromRect( Rect.fromPoints( button.localToGlobal(Offset(0, button.size.height), ancestor: overlay), button.localToGlobal(button.size.bottomRight(Offset.zero), ancestor: overlay), ), Offset.zero & overlay.size, ); // 弹出菜单,关闭后重置状态 showMenu( context: context, position: position, color: const Color(0xFF262533), items: <PopupMenuEntry>[ const PopupMenuItem( child: ListTile( title: Text( "Escortagenturen", style: TextStyle(color: Colors.white), ), ), ), const PopupMenuItem( child: ListTile( title: Text( "Bordelle", style: TextStyle(color: Colors.white), ), ), ), const PopupMenuItem( child: ListTile( title: Text( "Laufhauser", style: TextStyle(color: Colors.white), ), ), ), const PopupMenuItem( child: ListTile( title: Text( "Saunaclubs", style: TextStyle(color: Colors.white), ), ), ), const PopupMenuItem( child: ListTile( title: Text( "Domina & BDSM-Studios", style: TextStyle(color: Colors.white), ), ), ), const PopupMenuItem( child: ListTile( title: Text( "Tantra & Massaage-Studios", style: TextStyle(color: Colors.white), ), ), ), ], ).then((_) { setState(() => _isMenuOpen = false); }); } // 隐藏菜单 void _hideMenu() { if (_isMenuOpen) { Navigator.of(context).pop(); setState(() => _isMenuOpen = false); } } @override Widget build(BuildContext context) { return MouseRegion( key: _menuKey, onEnter: (_) => _showMenu(), onExit: (_) => _hideMenu(), child: const Text( "Agenturen & Clubs", style: TextStyle( color: Colors.white, fontSize: 24, fontFamily: "Poppins", ), ), ); } }
关键细节说明:
- 用
MouseRegion包裹触发文本,监听鼠标进入/离开事件,分别触发菜单的显示和隐藏。 - 通过
GlobalKey获取按钮的屏幕位置,确保菜单在按钮下方弹出(和你原本设置的PopupMenuPosition.under效果一致)。 - 手动调用
showMenu替代默认的点击触发逻辑,菜单关闭后自动重置状态,避免重复触发。
内容的提问来源于stack exchange,提问作者James James
相关产品推荐
相关产品推荐

