插件介绍

experimental/context_menus 是一个基于 Flutter 开发的实验性包,它允许开发者创建和自定义跨平台的上下文菜单,如移动设备上的文本选择工具栏或桌面设备上的右键菜单。该包提供了丰富的上下文菜单定制功能,支持 Material 和 Cupertino 两种设计风格,并已适配鸿蒙系统。

在这里插入图片描述

主要功能特点:

  • 支持在应用的任何位置创建自定义上下文菜单
  • 提供级联子菜单功能
  • 支持自定义菜单按钮和操作
  • 支持修改默认按钮的顺序和行为
  • 支持文本选择和非文本选择场景
  • 适配鸿蒙系统,提供一致的用户体验

如何在鸿蒙上使用

1. 引入依赖

由于这是一个实验性的自定义修改版本,需要以 git 形式引入。在你的鸿蒙项目的 pubspec.yaml 文件中添加以下依赖:

dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^1.0.2
  url_launcher: ^6.1.6
  context_menus:
    git:
      url: "https://github.com/flutter/samples.git"
      path: "experimental/context_menus"

2. 基本 API 介绍

该包提供了以下核心组件和 API:

ContextMenuRegion

这是创建自定义上下文菜单的核心组件,它包裹子组件并监听用户的右键点击或长按手势。

ContextMenuRegion({
  Key? key,
  required Widget child,
  required ContextMenuBuilder contextMenuBuilder,
});
ContextMenuBuilder

用于构建上下文菜单内容的回调函数。

typedef ContextMenuBuilder = Widget Function(BuildContext context, Offset offset);
ContextMenuController

用于控制上下文菜单的显示和隐藏。

final ContextMenuController _contextMenuController = ContextMenuController();

// 显示菜单
_contextMenuController.show(
  context: context,
  contextMenuBuilder: (context) => /* 菜单内容 */,
);

// 隐藏菜单
_contextMenuController.remove();

3. 使用示例

在任意位置创建上下文菜单
import 'package:flutter/material.dart';
import 'package:context_menus/context_menu_region.dart';

class AnywhereContextMenuExample extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return ContextMenuRegion(
      child: Container(
        color: Colors.blueGrey[50],
        padding: EdgeInsets.all(20),
        child: Center(
          child: Text('右键点击或长按(移动设备)显示上下文菜单'),
        ),
      ),
      contextMenuBuilder: (context, offset) {
        return Card(
          elevation: 8,
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              ListTile(
                leading: Icon(Icons.copy),
                title: Text('复制'),
                onTap: () {
                  // 处理复制操作
                  Navigator.pop(context);
                },
              ),
              ListTile(
                leading: Icon(Icons.cut),
                title: Text('剪切'),
                onTap: () {
                  // 处理剪切操作
                  Navigator.pop(context);
                },
              ),
              ListTile(
                leading: Icon(Icons.paste),
                title: Text('粘贴'),
                onTap: () {
                  // 处理粘贴操作
                  Navigator.pop(context);
                },
              ),
            ],
          ),
        );
      },
    );
  }
}
创建级联子菜单
import 'package:flutter/material.dart';
import 'package:context_menus/context_menu_region.dart';

class CascadingMenuExample extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return ContextMenuRegion(
      child: Container(
        color: Colors.green[50],
        padding: EdgeInsets.all(20),
        child: Center(
          child: Text('右键点击显示级联子菜单'),
        ),
      ),
      contextMenuBuilder: (context, offset) {
        return MenuBar(children: [
          SubmenuButton(
            menuChildren: [
              MenuItemButton(
                child: Text('选项 1'),
                onPressed: () {
                  // 处理选项 1
                  Navigator.pop(context);
                },
              ),
              MenuItemButton(
                child: Text('选项 2'),
                onPressed: () {
                  // 处理选项 2
                  Navigator.pop(context);
                },
              ),
            ],
            child: Text('主菜单'),
          ),
        ]);
      },
    );
  }
}
自定义文本选择菜单
import 'package:flutter/material.dart';

class CustomTextSelectionMenu extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return TextField(
      maxLines: null,
      decoration: InputDecoration(
        hintText: '输入文本,然后选择部分文本显示自定义菜单',
        border: OutlineInputBorder(),
        contentPadding: EdgeInsets.all(16),
      ),
      contextMenuBuilder: (context, editableTextState) {
        return AdaptiveTextSelectionToolbar.buttonItems(
          anchors: editableTextState.contextMenuAnchors,
          buttonItems: <ContextMenuButtonItem>[],
        );
      },
    );
  }
}
在图片上添加上下文菜单
import 'package:flutter/material.dart';
import 'package:context_menus/context_menu_region.dart';
import 'package:url_launcher/url_launcher.dart';

class ImageContextMenuExample extends StatelessWidget {
  final String imageUrl = 'https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=300';

  
  Widget build(BuildContext context) {
    return ContextMenuRegion(
      child: Card(
        elevation: 4,
        child: Image.network(imageUrl, width: 300, height: 200, fit: BoxFit.cover),
      ),
      contextMenuBuilder: (context, offset) {
        return Card(
          elevation: 8,
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              ListTile(
                leading: Icon(Icons.open_in_new),
                title: Text('在浏览器中打开'),
                onTap: () {
                  launchUrl(Uri.parse(imageUrl));
                  Navigator.pop(context);
                },
              ),
              ListTile(
                leading: Icon(Icons.copy),
                title: Text('复制图片链接'),
                onTap: () {
                  // 处理复制链接操作
                  Navigator.pop(context);
                },
              ),
              ListTile(
                leading: Icon(Icons.download),
                title: Text('下载图片'),
                onTap: () {
                  // 处理下载图片操作
                  Navigator.pop(context);
                },
              ),
            ],
          ),
        );
      },
    );
  }
}

总结

experimental/context_menus 是一个功能强大的 Flutter 包,它提供了丰富的上下文菜单定制功能,允许开发者在应用的任何位置创建自定义的上下文菜单。在鸿蒙系统上使用该包,你可以轻松实现一致的用户体验,并充分利用其丰富的功能特性。

使用步骤总结:

  1. pubspec.yaml 中以 git 形式添加依赖
  2. 使用 ContextMenuRegion 包裹需要添加上下文菜单的组件
  3. 通过 contextMenuBuilder 构建自定义的菜单内容
  4. 根据需要使用 ContextMenuController 控制菜单的显示和隐藏

该包支持多种使用场景,包括在任意位置创建菜单、级联子菜单、自定义文本选择菜单等,为开发者提供了极大的灵活性。

欢迎加入开源鸿蒙跨平台社区: https://openharmonycrossplatform.csdn.net

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐