Flutter悬浮窗管理插件flutter_overlay_window_fork的使用
Flutter悬浮窗管理插件flutter_overlay_window_fork的使用
Flutter插件,用于在其他应用程序之上显示您的Flutter应用程序。
Preview
TrueCaller overlay example | click-through overlay example | Messanger chat-head example |
---|---|---|
![]() |
![]() |
![]() |
Installation
在pubspec.yaml
文件中添加此包:
dependencies:
flutter_overlay_window: any # 或者使用最新版本
Android
您需要在AndroidManifest.xml中添加SYSTEM_ALERT_WINDOW
权限和OverlayService
。将explanation_for_special_use
替换为您自己的自定义说明。
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
<application>
...
<service android:name="flutter.overlay.window.flutter_overlay_window.OverlayService"
android:exported="false"
android:foregroundServiceType="specialUse">
<property android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
android:value="explanation_for_special_use"/>
</service>
</application>
Entry point
在main.dart
中创建一个用于Overlay小部件的入口点:
// overlay入口点
@pragma("vm:entry-point")
void overlayMain() {
runApp(const MaterialApp(
debugShowCheckedModeBanner: false,
home: Material(child: Text("My overlay"))
));
}
Usage
检查是否已授予悬浮窗权限:
/// 检查是否已授予悬浮窗权限
final bool status = await FlutterOverlayWindow.isPermissionGranted();
请求悬浮窗权限:
/// 请求悬浮窗权限
/// 它会打开悬浮窗设置页面,并在权限授予后返回 `true`
final bool status = await FlutterOverlayWindow.requestPermission();
打开悬浮窗内容:
/// 打开悬浮窗内容
///
/// - 可选参数:
///
/// `height` 悬浮窗高度,默认为 [WindowSize.fullCover]
///
/// `width` 悬浮窗宽度,默认为 [WindowSize.matchParent]
///
/// `alignment` 屏幕上的对齐位置,默认为 [OverlayAlignment.center]
///
/// `visibilitySecret` 锁屏时通知详细信息的可见性,默认为 [NotificationVisibility.visibilitySecret]
///
/// `OverlayFlag` 悬浮窗标志,默认为 [OverlayFlag.defaultFlag]
///
/// `overlayTitle` 通知消息,默认为 "overlay activated"
///
/// `overlayContent` 通知内容
///
/// `enableDrag` 是否允许拖动悬浮窗,默认为 `false`
///
/// `positionGravity` 拖动后的悬浮窗位置,默认为 [PositionGravity.none]
///
/// `startPosition` 悬浮窗初始位置,默认为 `null`
await FlutterOverlayWindow.showOverlay();
关闭悬浮窗:
/// 如果悬浮窗已打开,则关闭
await FlutterOverlayWindow.closeOverlay();
在主应用和悬浮窗之间广播数据:
/// 在主应用和悬浮窗之间共享数据
await FlutterOverlayWindow.shareData("Hello from the other side");
监听主应用和悬浮窗之间的共享事件:
/// 监听悬浮窗和主应用之间共享的消息
FlutterOverlayWindow.overlayListener.listen((event) {
print("当前事件: $event");
});
当需要使用键盘输入字段时启用焦点模式:
/// 当您想要使用需要键盘输入的字段时启用 [OverlayFlag.focusPointer]
await FlutterOverlayWindow.showOverlay(flag: OverlayFlag.focusPointer);
更新悬浮窗标志:
/// 在悬浮窗运行时更新标志
await FlutterOverlayWindow.updateFlag(OverlayFlag.defaultFlag);
更新悬浮窗在屏幕上的大小:
/// 更新悬浮窗在屏幕上的大小
await FlutterOverlayWindow.resizeOverlay(80, 120);
更新悬浮窗在屏幕上的位置:
/// 更新悬浮窗在屏幕上的位置
///
/// `position` 新的位置
///
/// `return` 如果位置成功更新则返回 `true`
await FlutterOverlayWindow.moveOverlay(OverlayPosition(0, 156));
获取当前悬浮窗的位置:
/// 获取当前悬浮窗的位置
///
/// `return` 当前悬浮窗的位置
await FlutterOverlayWindow.getOverlayPosition();
枚举类定义
悬浮窗标志枚举:
enum OverlayFlag {
/// 窗口标志:该窗口永远不会接收触摸事件。
/// 如果您想显示点击通过的悬浮窗,可以使用此标志。
clickThrough,
/// 窗口标志:该窗口不会接收任何按键输入焦点。
/// 用户无法向其发送键或其他按钮事件。
defaultFlag,
/// 窗口标志:允许任何窗口外的指针事件被发送到其后面的窗口。
/// 当您希望使用需要键盘输入的字段时,可以使用此标志。
focusPointer,
}
悬浮窗拖动行为枚举:
/// 悬浮窗拖动行为类型。
enum PositionGravity {
/// `PositionGravity.none` 允许悬浮窗放置在屏幕上的任意位置。
none,
/// `PositionGravity.right` 允许悬浮窗粘附在屏幕右侧。
right,
/// `PositionGravity.left` 允许悬浮窗粘附在屏幕左侧。
left,
/// `PositionGravity.auto` 允许悬浮窗根据当前位置粘附在屏幕左侧或右侧。
auto,
}
更多关于Flutter悬浮窗管理插件flutter_overlay_window_fork的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter悬浮窗管理插件flutter_overlay_window_fork的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
flutter_overlay_window_fork
是一个用于在 Flutter 应用中创建和管理悬浮窗的插件。它允许你在应用的其他界面之上显示一个独立的悬浮窗口,适用于需要常驻显示一些信息或操作的情况,比如显示当前播放的音乐、悬浮球等。
以下是如何使用 flutter_overlay_window_fork
插件的基本步骤:
1. 添加依赖
首先,在 pubspec.yaml
文件中添加 flutter_overlay_window_fork
插件的依赖:
dependencies:
flutter:
sdk: flutter
flutter_overlay_window_fork: ^0.0.1 # 请查看最新版本
然后运行 flutter pub get
来获取依赖。
2. 请求悬浮窗权限
在 Android 上,使用悬浮窗功能需要请求 SYSTEM_ALERT_WINDOW
权限。你需要在 AndroidManifest.xml
文件中添加以下权限声明:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
然后,你需要在运行时请求这个权限:
import 'package:flutter_overlay_window_fork/flutter_overlay_window_fork.dart';
Future<void> requestOverlayPermission() async {
if (!await FlutterOverlayWindowFork.isPermissionGranted()) {
await FlutterOverlayWindowFork.requestPermission();
}
}
3. 创建悬浮窗
你可以使用 FlutterOverlayWindowFork.showOverlay
方法来创建一个悬浮窗。这个方法需要传递一个 OverlayWindowConfig
对象来配置悬浮窗的行为和外观。
import 'package:flutter/material.dart';
import 'package:flutter_overlay_window_fork/flutter_overlay_window_fork.dart';
void showOverlayWindow() async {
await FlutterOverlayWindowFork.showOverlay(
overlayWindowConfig: OverlayWindowConfig(
width: 200,
height: 200,
alignment: OverlayAlignment.center,
gravity: OverlayGravity.center,
overlayContent: (BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.transparent,
body: Center(
child: Container(
width: 200,
height: 200,
color: Colors.blue,
child: Center(
child: Text(
'悬浮窗内容',
style: TextStyle(color: Colors.white),
),
),
),
),
),
);
},
),
);
}
4. 关闭悬浮窗
你可以使用 FlutterOverlayWindowFork.closeOverlay
方法来关闭悬浮窗:
void closeOverlayWindow() async {
await FlutterOverlayWindowFork.closeOverlay();
}
5. 处理悬浮窗的生命周期
你可以通过监听悬浮窗的生命周期事件来处理悬浮窗的显示和隐藏:
FlutterOverlayWindowFork.overlayWindowLifecycleStream.listen((event) {
if (event == OverlayWindowLifecycleEvent.show) {
print('悬浮窗显示');
} else if (event == OverlayWindowLifecycleEvent.hide) {
print('悬浮窗隐藏');
}
});
6. 处理悬浮窗的点击事件
你可以在悬浮窗的内容中添加点击事件处理逻辑:
overlayContent: (BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.transparent,
body: Center(
child: GestureDetector(
onTap: () {
print('悬浮窗被点击');
},
child: Container(
width: 200,
height: 200,
color: Colors.blue,
child: Center(
child: Text(
'悬浮窗内容',
style: TextStyle(color: Colors.white),
),
),
),
),
),
),
);
},
7. 处理悬浮窗的拖拽事件
你可以在悬浮窗的内容中添加拖拽事件处理逻辑:
overlayContent: (BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.transparent,
body: Center(
child: Draggable(
child: Container(
width: 200,
height: 200,
color: Colors.blue,
child: Center(
child: Text(
'拖拽我',
style: TextStyle(color: Colors.white),
),
),
),
feedback: Container(
width: 200,
height: 200,
color: Colors.blue.withOpacity(0.5),
child: Center(
child: Text(
'拖拽中',
style: TextStyle(color: Colors.white),
),
),
),
childWhenDragging: Container(),
onDragEnd: (details) {
print('拖拽结束');
},
),
),
),
);
},
8. 其他配置
你还可以通过 OverlayWindowConfig
对象配置悬浮窗的其他行为,比如悬浮窗的位置、大小、是否可拖动等。
9. 注意事项
- 在 Android 上,悬浮窗功能需要用户手动授予
SYSTEM_ALERT_WINDOW
权限。 - 悬浮窗的内容是一个独立的 Flutter 应用,因此它有自己的
MaterialApp
和Scaffold
。 - 悬浮窗的生命周期与主应用的生命周期是独立的,因此需要注意资源的管理和释放。
10. 示例代码
以下是一个完整的示例代码,展示了如何创建、显示、关闭悬浮窗,并处理悬浮窗的生命周期和点击事件:
import 'package:flutter/material.dart';
import 'package:flutter_overlay_window_fork/flutter_overlay_window_fork.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: HomeScreen(),
);
}
}
class HomeScreen extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('悬浮窗示例'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () async {
await requestOverlayPermission();
showOverlayWindow();
},
child: Text('显示悬浮窗'),
),
ElevatedButton(
onPressed: () {
closeOverlayWindow();
},
child: Text('关闭悬浮窗'),
),
],
),
),
);
}
}
Future<void> requestOverlayPermission() async {
if (!await FlutterOverlayWindowFork.isPermissionGranted()) {
await FlutterOverlayWindowFork.requestPermission();
}
}
void showOverlayWindow() async {
await FlutterOverlayWindowFork.showOverlay(
overlayWindowConfig: OverlayWindowConfig(
width: 200,
height: 200,
alignment: OverlayAlignment.center,
gravity: OverlayGravity.center,
overlayContent: (BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.transparent,
body: Center(
child: GestureDetector(
onTap: () {
print('悬浮窗被点击');
},
child: Container(
width: 200,
height: 200,
color: Colors.blue,
child: Center(
child: Text(
'悬浮窗内容',
style: TextStyle(color: Colors.white),
),
),
),
),
),
),
);
},
),
);
}
void closeOverlayWindow() async {
await FlutterOverlayWindowFork.closeOverlay();
}