Flutter快捷菜单扩展插件shortcut_menu_extender的使用
Flutter快捷菜单扩展插件shortcut_menu_extender的使用
该插件允许Flutter应用扩展全局快捷菜单。
平台支持
Linux | macOS | Windows |
---|---|---|
- | - | ✔️ |
快速开始
安装
在你的pubspec.yaml
文件中添加以下依赖:
dependencies:
shortcut_menu_extender: ^0.1.1
然后运行flutter pub get
来安装该依赖。
使用
Windows
首先,修改文件windows/runner/main.cpp
如下:
#include <flutter/dart_project.h>
#include <flutter/flutter_view_controller.h>
#include <windows.h>
#include "flutter_window.h"
#include "utils.h"
#include <shortcut_menu_extender_windows/shortcut_menu_extender_windows_plugin_c_api.h>
int APIENTRY wWinMain(_In_ HINSTANCE instance,
_In_opt_ HINSTANCE prev,
_In_ wchar_t* command_line,
_In_ int show_command) {
HANDLE instance_mutex =
CreateMutex(NULL, TRUE, L"shortcut_menu_extender_example");
if (GetLastError() == ERROR_ALREADY_EXISTS &&
!ShouldHandleByShortcutMenuExtenderCommand()) {
HWND hwnd = ::FindWindow(L"FLUTTER_RUNNER_WIN32_WINDOW",
L"shortcut_menu_extender_example");
if (hwnd != NULL && ShouldHandleByShortcutMenuExtender()) {
DispatchToShortcutMenuExtender(hwnd);
}
CloseHandle(instance_mutex);
return EXIT_SUCCESS;
}
// Attach to console when present (e.g., 'flutter run') or create a
// new console when running with a debugger.
if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) {
CreateAndAttachConsole();
}
// Initialize COM, so that it is available for use in the library and/or
// plugins.
::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
flutter::DartProject project(L"data");
std::vector<std::string> command_line_arguments = GetCommandLineArguments();
project.set_dart_entrypoint_arguments(std::move(command_line_arguments));
FlutterWindow window(project);
Win32Window::Point origin(10, 10);
Win32Window::Size size(1280, 720);
if (!window.Create(L"shortcut_menu_extender_example", origin, size)) {
return EXIT_FAILURE;
}
window.SetQuitOnClose(true);
::MSG msg;
while (::GetMessage(&msg, nullptr, 0, 0)) {
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
::CoUninitialize();
return EXIT_SUCCESS;
}
接下来,在你的主入口文件(如main.dart
)中初始化并使用该插件:
import 'package:shortcut_menu_extender/shortcut_menu_extender.dart';
void main() async {
// 必须添加这一行。
WidgetsFlutterBinding.ensureInitialized();
if (shortcutMenuExtenderCommand.runIfNeeded(args)) exit(0);
runApp(MyApp());
}
注册/注销
注册一个快捷菜单项:
shortcutMenuExtender.register(
'MyFlutterApp',
name: 'Open With MyFlutterApp',
executable: Platform.resolvedExecutable,
useDefaultIcon: true,
);
注销一个快捷菜单项:
shortcutMenuExtender.unregister(
'MyFlutterApp',
);
监听事件
创建一个状态管理类,并实现ShortcutMenuListener
接口:
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
[@override](/user/override)
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> with ShortcutMenuListener {
[@override](/user/override)
void initState() {
shortcutMenuExtender.addListener(this);
super.initState();
}
[@override](/user/override)
void dispose() {
shortcutMenuExtender.removeListener(this);
super.dispose();
}
[@override](/user/override)
Widget build(BuildContext context) {
// 构建你的UI
}
[@override](/user/override)
void onShortcutMenuClicked(String key, String path) {
print('onShortcutMenuClicked: $key, $path');
}
}
请参阅该插件的示例应用以获取完整的示例。
赞助商
cmlanche |
许可证
示例代码
以下是example/lib/main.dart
的完整示例代码:
import 'dart:async';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:shortcut_menu_extender/shortcut_menu_extender.dart';
const _kShortcutMenuKeyMyFlutterApp = 'MyFlutterApp';
const _kShortcutMenuKeyMyFlutterApp2 = 'MyFlutterApp2';
void main(List<String> args) {
WidgetsFlutterBinding.ensureInitialized();
if (shortcutMenuExtenderCommand.runIfNeeded(args)) exit(0);
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
[@override](/user/override)
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> with ShortcutMenuListener {
String _platformVersion = 'Unknown';
final _shortcutMenuExtenderPlugin = ShortcutMenuExtender();
final List<FileSystemEntity> _entities = [];
[@override](/user/override)
void initState() {
shortcutMenuExtender.addListener(this);
super.initState();
initPlatformState();
}
[@override](/user/override)
void dispose() {
shortcutMenuExtender.removeListener(this);
super.dispose();
}
// 平台消息是异步的,所以我们在这里初始化。
Future<void> initPlatformState() async {
String platformVersion;
// 平台消息可能会失败,所以我们使用try/catch处理PlatformException。
// 我们还处理消息可能返回null的情况。
try {
platformVersion =
await _shortcutMenuExtenderPlugin.getPlatformVersion() ?? 'Unknown platform version';
} on PlatformException {
platformVersion = 'Failed to get platform version.';
}
// 如果小部件在异步平台消息飞行时从树中移除,我们希望丢弃回复而不是调用setState更新我们的不存在的外观。
if (!mounted) return;
setState(() {
_platformVersion = platformVersion;
});
}
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Column(
children: [
Text('Running on: $_platformVersion\n'),
ElevatedButton(
onPressed: () {
shortcutMenuExtender.register(
_kShortcutMenuKeyMyFlutterApp,
name: 'Open with MyFlutterApp',
executable: Platform.resolvedExecutable,
useDefaultIcon: true,
);
},
child: const Text('register MyFlutterApp'),
),
ElevatedButton(
onPressed: () {
shortcutMenuExtender.unregister(
_kShortcutMenuKeyMyFlutterApp,
);
},
child: const Text('unregister MyFlutterApp'),
),
ElevatedButton(
onPressed: () {
shortcutMenuExtender.register(
_kShortcutMenuKeyMyFlutterApp2,
name: '用我的FlutterApp打开',
executable: Platform.resolvedExecutable,
useDefaultIcon: false,
);
},
child: const Text('register 我的MyFlutterApp2'),
),
ElevatedButton(
onPressed: () {
shortcutMenuExtender.unregister(
_kShortcutMenuKeyMyFlutterApp2,
);
},
child: const Text('unregister 我的FlutterApp2'),
),
Expanded(
child: ListView(
children: [
for (final entity in _entities)
ListTile(
title: Text(entity.statSync().type.toString()),
subtitle: Text(entity.path),
),
],
),
),
],
),
),
);
}
[@override](/user/override)
void onShortcutMenuClicked(String key, String path) {
if (key == _kShortcutMenuKeyMyFlutterApp) {
final type = FileSystemEntity.typeSync(path);
if (type == FileSystemEntityType.file) {
_entities.add(File(path));
} else if (type == FileSystemEntityType.directory) {
_entities.add(Directory(path));
}
setState(() {});
} else if (key == _kShortcutMenuKeyMyFlutterApp2) {
if (kDebugMode) {
print('key: $key, path: $path');
}
}
}
}
更多关于Flutter快捷菜单扩展插件shortcut_menu_extender的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter快捷菜单扩展插件shortcut_menu_extender的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何使用 shortcut_menu_extender
插件在 Flutter 中实现快捷菜单的示例代码。这个插件允许你扩展快捷菜单的功能,为应用添加更多的交互选项。
首先,确保你已经在 pubspec.yaml
文件中添加了 shortcut_menu_extender
依赖:
dependencies:
flutter:
sdk: flutter
shortcut_menu_extender: ^最新版本号 # 请替换为实际最新版本号
然后,运行 flutter pub get
来获取依赖。
接下来,在你的 Flutter 应用中实现快捷菜单。以下是一个简单的示例,展示如何使用 shortcut_menu_extender
:
import 'package:flutter/material.dart';
import 'package:shortcut_menu_extender/shortcut_menu_extender.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Shortcut Menu Extender Example'),
),
body: Center(
child: GestureDetector(
onLongPress: () {
// 显示快捷菜单
showShortcutMenu(
context: context,
items: [
ShortcutMenuItem(
icon: Icons.edit,
label: 'Edit',
onTap: () {
// 编辑操作
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Edit tapped')),
);
},
),
ShortcutMenuItem(
icon: Icons.delete,
label: 'Delete',
onTap: () {
// 删除操作
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Delete tapped')),
);
},
),
ShortcutMenuItem(
icon: Icons.share,
label: 'Share',
onTap: () {
// 分享操作
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Share tapped')),
);
},
),
],
);
},
child: Container(
width: 100,
height: 100,
color: Colors.blue,
child: Center(child: Text('Long Press Me')),
),
),
),
),
);
}
}
// 快捷菜单项定义
class ShortcutMenuItem {
final IconData icon;
final String label;
final VoidCallback onTap;
ShortcutMenuItem({required this.icon, required this.label, required this.onTap});
}
// 显示快捷菜单的函数
Future<void> showShortcutMenu({
required BuildContext context,
required List<ShortcutMenuItem> items,
}) async {
final renderBox = context.findRenderObject() as RenderBox;
final position = renderBox.localToGlobal(Offset.zero);
await showMenu<void>(
context: context,
position: RelativeRect.fromLTRB(
position.dx,
position.dy + renderBox.size.height,
0.0,
0.0,
),
items: items.map<PopupMenuItem<void>>((ShortcutMenuItem item) {
return PopupMenuItem<void>(
value: null,
child: Row(
children: <Widget>[
Icon(item.icon),
SizedBox(width: 10),
Text(item.label),
],
),
onTap: item.onTap,
);
}).toList(),
);
}
代码说明
- 依赖添加:在
pubspec.yaml
中添加shortcut_menu_extender
依赖。 - 主应用:创建一个简单的 Flutter 应用,包含一个可长按的
GestureDetector
。 - 快捷菜单项:定义一个
ShortcutMenuItem
类来存储每个菜单项的图标、标签和点击回调。 - 显示快捷菜单:定义一个
showShortcutMenu
函数,使用showMenu
方法显示快捷菜单。 - 位置计算:通过
localToGlobal
方法将GestureDetector
的位置转换为全局坐标,以便正确显示快捷菜单的位置。
这段代码展示了如何使用 shortcut_menu_extender
的概念(虽然实际上 shortcut_menu_extender
可能是一个假设的插件名称,Flutter 社区中可能有类似的插件,但具体实现可能有所不同)。在实际使用中,你可能需要查阅该插件的官方文档来适应具体的 API 和用法。