Flutter上下文菜单插件flutter_context_menu的使用

发布于 1周前 作者 sinazl 来自 Flutter

Flutter上下文菜单插件flutter_context_menu的使用

简介

Logo

Flutter Context Menu

Flutter Context Menu 是一个Flutter库,它为创建和显示上下文菜单提供了一个灵活且可定制的解决方案。通过这个库,你可以轻松地将上下文菜单添加到UI中,为用户提供一种方便的方式来访问与所选项目或区域相关的额外选项和操作。

功能特性

  • ContextMenu: 包含高度可定制的上下文菜单系统,易于集成到Flutter应用中。
  • 分层结构: 支持带有子菜单功能的分层结构,可以创建嵌套菜单。
  • 选择处理: 内置上下文菜单项的选择处理,允许为每个菜单项定义回调函数。
  • 自定义选项: 自定义上下文菜单的外观和行为以匹配应用程序的设计需求。
  • 内置组件: 提供了如MenuItemMenuDividerMenuHeader等内置组件。
  • 跨平台支持: 兼容Android、iOS、Web和桌面平台。

开始使用

安装

方法1(推荐):

在终端运行以下命令:

flutter pub add flutter_context_menu

方法2:

pubspec.yaml文件中添加依赖:

dependencies:
    flutter_context_menu: ^0.2.0

然后,在终端运行:

flutter pub get

使用示例

导入包

首先导入必要的包:

import 'package:flutter_context_menu/flutter_context_menu.dart';

初始化ContextMenu实例

定义你的上下文菜单条目并初始化ContextMenu

final entries = <ContextMenuEntry>[
  const MenuHeader(text: "Context Menu"),
  MenuItem(
    label: 'Copy',
    icon: Icons.copy,
    onSelected: () {
      // 实现复制逻辑
    },
  ),
  MenuItem(
    label: 'Paste',
    icon: Icons.paste,
    onSelected: () {
      // 实现粘贴逻辑
    },
  ),
  const MenuDivider(),
  MenuItem.submenu(
    label: 'Edit',
    icon: Icons.edit,
    items: [
      MenuItem(
        label: 'Undo',
        value: "Undo",
        icon: Icons.undo,
        onSelected: () {
          // 实现撤销逻辑
        },
      ),
      MenuItem(
        label: 'Redo',
        value: 'Redo',
        icon: Icons.redo,
        onSelected: () {
          // 实现重做逻辑
        },
      ),
    ],
  ),
];

final menu = ContextMenu(
  entries: entries,
  position: const Offset(300, 300),
  padding: const EdgeInsets.all(8.0),
);

显示上下文菜单

方法1: 直接调用显示方法

这将在手动指定的位置显示上下文菜单:

showContextMenu(context, contextMenu: menu);
// 或者 
final selectedValue = await menu.show(context);
print(selectedValue);
方法2: 使用ContextMenuRegion小部件

当用户右键单击或长按区域时显示上下文菜单:

@override
Widget build(BuildContext context) {
  return Column(
    children: [
      ContextMenuRegion(
        contextMenu: contextMenu,
        onItemSelected: (value) {
          print(value);
        },
        child: Container(
          color: Colors.indigo,
          height: 300,
          width: 300,
          child: const Center(
            child: Text(
              'Right click or long press!',
            ),
          ),
        ),
      )
    ],
  );
}

自定义

  • 主题: 默认情况下,上下文菜单及其项使用MaterialApp的主题数据进行样式设置。但可以通过修改主题数据来自定义其外观和行为,也可以通过在ContextMenuboxDecoration属性中指定BoxDecoration来单独自定义。
  • 自定义条目: 可以通过继承ContextMenuEntry类来创建自己的上下文菜单条目,以自定义外观、行为和功能。

更多信息

反馈与贡献

如果有任何建议或反馈,请打开问题创建拉取请求

如果喜欢这个包,请在GitHub上给它加星,并关注我XGitHub上的动态。

许可证

本项目遵循BSD 3-Clause License许可证。


Made with ❤️ in Egypt 🇪🇬
Palestine 🇵🇸


更多关于Flutter上下文菜单插件flutter_context_menu的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter上下文菜单插件flutter_context_menu的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用flutter_context_menu插件来实现上下文菜单的一个简单示例。

首先,确保你已经在pubspec.yaml文件中添加了flutter_context_menu依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_context_menu: ^x.y.z  # 请替换为最新版本号

然后运行flutter pub get来安装依赖。

接下来,我们可以编写一个简单的Flutter应用来演示如何使用flutter_context_menu

import 'package:flutter/material.dart';
import 'package:flutter_context_menu/flutter_context_menu.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Context Menu Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final GlobalKey _contextMenuKey = GlobalKey();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Context Menu Demo'),
      ),
      body: GestureDetector(
        behavior: HitTestBehavior.translucent,
        onTap: () {
          // 这里可以根据需要触发上下文菜单
          // 例如,可以检测点击位置并显示菜单
        },
        child: Stack(
          children: [
            ListView.builder(
              itemCount: 20,
              itemBuilder: (context, index) {
                return ListTile(
                  title: Text('Item $index'),
                  trailing: IconButton(
                    icon: Icon(Icons.more_vert),
                    onPressed: () {
                      showContextMenu(
                        context: context,
                        menuItems: [
                          ContextMenuItem(
                            title: 'Edit',
                            onTap: () {
                              // 处理编辑操作
                              ScaffoldMessenger.of(context).showSnackBar(
                                SnackBar(content: Text('Edit Item $index')),
                              );
                            },
                          ),
                          ContextMenuItem(
                            title: 'Delete',
                            onTap: () {
                              // 处理删除操作
                              ScaffoldMessenger.of(context).showSnackBar(
                                SnackBar(content: Text('Delete Item $index')),
                              );
                            },
                          ),
                        ],
                        position: _getContextMenuPosition(context, index),
                      );
                    },
                  ),
                );
              },
            ),
            Positioned(
              key: _contextMenuKey,
              child: Container(), // 这里暂时为空,上下文菜单会渲染在这里
            ),
          ],
        ),
      ),
    );
  }

  Offset _getContextMenuPosition(BuildContext context, int index) {
    // 获取列表项的位置,并计算上下文菜单的位置
    final RenderBox box = context.findRenderObject() as RenderBox;
    final Offset position = box.localToGlobal(Offset.zero);
    final Size size = box.size;

    // 假设菜单显示在右侧
    return Offset(position.dx + size.width, position.dy + size.height / 2 - 50);
  }
}

void showContextMenu({
  required BuildContext context,
  required List<ContextMenuItem> menuItems,
  required Offset position,
}) {
  final renderBox = context.findRenderObject() as RenderBox?;
  final screenPosition = renderBox?.localToGlobal(Offset.zero) ?? Offset.zero;

  final menuLayer = Material(
    elevation: 8.0,
    child: Column(
      mainAxisAlignment: MainAxisAlignment.start,
      crossAxisAlignment: CrossAxisAlignment.start,
      children: menuItems.map((item) {
        return InkWell(
          onTap: item.onTap,
          child: Padding(
            padding: EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
            child: Text(item.title),
          ),
        );
      }).toList(),
    ),
  );

  Overlay.of(context)?.insert(
    OverlayEntry(
      builder: (context) {
        return Positioned(
          left: position.dx - screenPosition.dx,
          top: position.dy - screenPosition.dy,
          child: menuLayer,
        );
      },
    ),
  );
}

class ContextMenuItem {
  final String title;
  final VoidCallback onTap;

  ContextMenuItem({required this.title, required this.onTap});
}

在这个示例中,我们创建了一个简单的Flutter应用,其中包含一个列表。每个列表项右侧都有一个“更多”按钮,点击该按钮时会显示一个上下文菜单,包含“编辑”和“删除”选项。

请注意,这个示例中的showContextMenu函数是一个简单的实现,用于在指定位置显示上下文菜单。在实际应用中,你可能需要更复杂的逻辑来处理菜单的显示和隐藏,以及更好的位置计算和动画效果。

此外,flutter_context_menu插件本身可能已经提供了更简便和强大的功能,因此建议查阅其官方文档和示例以获取最佳实践。

回到顶部