当前位置: 首页> 财经> 金融 > 嘉兴seo网站建设_个人简历模板免费下载word文档_360网站收录提交入口_seo关键词词库

嘉兴seo网站建设_个人简历模板免费下载word文档_360网站收录提交入口_seo关键词词库

时间:2025/7/27 14:53:18来源:https://blog.csdn.net/axuanqq/article/details/147198173 浏览次数:0次
嘉兴seo网站建设_个人简历模板免费下载word文档_360网站收录提交入口_seo关键词词库

​在 Flutter 桌面应用开发中,context_menucontextual_menu 是两款常用的右键菜单插件,各有特色。以下是对它们的对比分析:​


context_menu

  • 集成方式:​通过 ContextMenuArea 组件包裹目标组件,定义菜单项。​掘金

  • 菜单定义:​使用 builder 返回一个 List<Widget>,通常为 ListTile,支持图标、文字和点击事件。​掘金

  • 适用场景:​适合需要快速实现简单右键菜单的场景,集成方便,适用于大多数桌面应用。​掘金


contextual_menu

  • 集成方式:​需要手动监听鼠标右键事件,并调用 popUpContextualMenu() 方法显示菜单。​掘金

  • 菜单定义:​使用 MenuMenuItem 结构,支持普通项、复选框、分隔符和子菜单等多种类型。​掘金

  • 适用场景:​适合需要复杂菜单结构(如多级菜单、复选项)的应用,提供更高的自定义能力。​


总结对比

特性context_menucontextual_menu
集成方式使用组件包裹目标组件,集成简单手动监听事件,调用方法显示菜单,集成复杂
菜单结构简单,适合基本菜单复杂,支持多级菜单、复选项等
自定义能力限制较多,主要通过 ListTile 实现高度自定义,支持多种菜单项类型
适用场景快速实现基本右键菜单实现复杂、结构化的右键菜单

建议选择

  • 选择 context_menu:​如果你需要快速集成一个简单的右键菜单,且菜单项较为基础,context_menu 是一个不错的选择。​

  • 选择 contextual_menu:​如果你的应用需要复杂的菜单结构,如多级菜单、复选项等,contextual_menu 提供了更强大的功能和灵活性。

contextmenu

hello word

引入依赖

  contextmenu: ^3.0.0
import 'package:contextmenu/contextmenu.dart';
import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter Demo',theme: ThemeData(colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),),home: const MyHomePage(title: 'Flutter Demo Home Page'),);}
}class MyHomePage extends StatefulWidget {const MyHomePage({super.key, required this.title});final String title;@overrideState<MyHomePage> createState() => _MyHomePageState();
}class _MyHomePageState extends State<MyHomePage> {@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(backgroundColor: Theme.of(context).colorScheme.inversePrimary,title: Text(widget.title),),body: ContextMenuArea(child: Container(color: Colors.grey,padding: EdgeInsets.all(20),child: Text("在这里右键"),),builder: (BuildContext context) {return [Container(padding: EdgeInsets.all(10), child: Text('自定义菜单')),ListTile(title: Text("点击"),onTap: () {ScaffoldMessenger.of(context,).showSnackBar(SnackBar(content: Text("点击了")));},),];},), // This trailing comma makes auto-formatting nicer for build methods.);}
}

自定义弹出位置

          ///完全自定义位置GestureDetector(onSecondaryTapDown:(details) => showContextMenu(details.globalPosition,context,(BuildContext context) {return [Container(padding: EdgeInsets.all(10),child: Text('自定义菜单'),),ListTile(title: Text("点击"),onTap: () {ScaffoldMessenger.of(context,).showSnackBar(SnackBar(content: Text("点击了")));},),];},0.0,200.0,),child: Container(padding: EdgeInsets.all(15),color: Colors.green,child: Text('Tap!'),),),

contextual_menu

hello word

https://pub.dev/packages/contextual_menu

contextual_menu: ^0.1.2
        GestureDetector(onSecondaryTapDown: (details) {Menu menu = Menu(items: [MenuItem(label: 'Copy',onClick: (_) {print('Clicked Copy');},),MenuItem(label: 'Disabled item', disabled: true),MenuItem.checkbox(key: 'checkbox1',label: 'Checkbox1',checked: true,onClick: (menuItem) {print('Clicked Checkbox1');menuItem.checked = !(menuItem.checked == true);},),MenuItem.separator(),],);popUpContextualMenu(menu, placement: Placement.bottomLeft);},child: Container(padding: EdgeInsets.all(15),color: Colors.green,child: Text('Tap!'),),),

popUpContextualMenu

可以看到我们本身没有传递position参数,那么他是怎么感知我鼠标点击的位置呢

他是通过window记录的鼠标点击位置来展示的

NSWindow.mouseLocationOutsideOfEventStream 是 macOS 平台(AppKit 框架)中的一个属性,用于获取当前鼠标在指定窗口中的坐标位置,而不是通过事件触发获取的。这个方法非常实用,尤其是在没有发生鼠标事件时,仍然需要获取当前鼠标位置的场景下。

var mouseLocationOutsideOfEventStream: NSPoint { get }

  • 返回值:一个 NSPoint,表示鼠标相对于窗口坐标系的位置。

  • 类型:NSWindow 的实例属性。

自定义ContextMenuArea


在contextmenu中我们看到ContextMenuArea包装使用非常简单,我们这里用contextual_menu也包装一个

import 'dart:ui';import 'package:contextual_menu/contextual_menu.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/gestures.dart';typedef ContextMenuBuilder = List<MenuItem> Function(BuildContext context);class ContextualMenuArea extends StatefulWidget {final Widget child;final ContextMenuBuilder builder;const ContextualMenuArea({super.key,required this.child,required this.builder,});@overrideState<StatefulWidget> createState() {return ContextualMenuAreaState();}
}class ContextualMenuAreaState extends State<ContextualMenuArea> {bool _shouldReact = false;Offset? _position;@overrideWidget build(BuildContext context) {return Listener(child: widget.child,onPointerDown: (details) {///kSecondaryMouseButton	0x02	次键(一般是右键)///PointerDeviceKind.mouse 输入来源是鼠标_shouldReact =details.kind == PointerDeviceKind.mouse &&details.buttons == kSecondaryMouseButton;},onPointerUp: (details) {if (!_shouldReact) return;_position = details.position;_handleClickPopUp();},);}void _handleClickPopUp() {popUpContextualMenu(Menu(items: widget.builder(context)),position: _position,placement: Placement.bottomRight,);}
}

使用方式

ContextualMenuArea(child: Container(padding: EdgeInsets.all(20),color: Colors.grey,child: Text("ContextualMenuArea"),),builder: (context) {return [MenuItem.submenu(label: "复制",submenu: Menu(items: [MenuItem.checkbox(label: "复制全部", checked: false),MenuItem.checkbox(label: "复制当前", checked: true),],),),MenuItem.separator(),MenuItem(label: "粘贴"),];},)

运行效果

关键字:嘉兴seo网站建设_个人简历模板免费下载word文档_360网站收录提交入口_seo关键词词库

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: