在鸿蒙上使用 experimental/context_menus Flutter Package
experimental/context_menus 是一个 Flutter 实验性插件,用于创建跨平台自定义上下文菜单(右键/长按菜单)。支持 Material 和 Cupertino 设计风格,适配鸿蒙系统,提供级联子菜单、自定义按钮等功能。通过 ContextMenuRegion 组件包裹子控件并监听交互事件,ContextMenuBuilder 构建菜单内容,ContextMenuCont
插件介绍
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 包,它提供了丰富的上下文菜单定制功能,允许开发者在应用的任何位置创建自定义的上下文菜单。在鸿蒙系统上使用该包,你可以轻松实现一致的用户体验,并充分利用其丰富的功能特性。
使用步骤总结:
- 在
pubspec.yaml中以 git 形式添加依赖 - 使用
ContextMenuRegion包裹需要添加上下文菜单的组件 - 通过
contextMenuBuilder构建自定义的菜单内容 - 根据需要使用
ContextMenuController控制菜单的显示和隐藏
该包支持多种使用场景,包括在任意位置创建菜单、级联子菜单、自定义文本选择菜单等,为开发者提供了极大的灵活性。
欢迎加入开源鸿蒙跨平台社区: https://openharmonycrossplatform.csdn.net
更多推荐


所有评论(0)