Flutter触摸服务插件touch_service_plugin的使用
Flutter触摸服务插件touch_service_plugin的使用
简介
touch_service_plugin
是一个用于在Android平台上集成无障碍服务(Accessibility Service)的Flutter插件。该插件允许应用程序执行触摸和滑动操作。
完整示例
首先,确保你已经添加了 touch_service_plugin
到你的 pubspec.yaml
文件中:
dependencies:
flutter:
sdk: flutter
touch_service_plugin: ^<最新版本号>
然后运行 flutter pub get
来安装依赖。
接下来,我们将通过一个完整的示例来展示如何使用 touch_service_plugin
。
import 'dart:async';
import 'dart:log';
import 'dart:isolate';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter_overlay_window/flutter_overlay_window.dart';
import 'package:touch_service_plugin/models.dart';
import 'package:touch_service_plugin/touch_api.g.dart';
import 'package:touch_service_plugin/touch_service_plugin.dart';
import 'package:touch_service_plugin_example/overlay_main.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class TouchPoint {
final double x;
final double y;
final int delay;
TouchPoint(this.x, this.y, this.delay);
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
[@override](/user/override)
State<MyHomePage> createState() => _MyHomePageState();
}
[@pragma](/user/pragma)("vm:entry-point")
void overlayMain() {
WidgetsFlutterBinding.ensureInitialized();
runApp(
const MaterialApp(
debugShowCheckedModeBanner: false,
home: SafeArea(child: OverlayMain()),
),
);
}
class _MyHomePageState extends State<MyHomePage> {
double _tabPositionX = 0;
double _tabPositionY = 0;
String _text = "No touch";
static const String _kPortNameOverlay = 'OVERLAY';
static const String _kPortNameHome = 'UI';
final _receivePort = ReceivePort();
SendPort? homePort;
String? latestMessageFromOverlay;
[@override](/user/override)
void initState() {
super.initState();
if (homePort != null) return;
final res = IsolateNameServer.registerPortWithName(
_receivePort.sendPort,
_kPortNameHome,
);
log("$res: OVERLAY");
_receivePort.listen((message) {
log("message from OVERLAY: $message");
if (message == "Subscribe") {
_subscribeAccessibility();
} else if (message == "Cancel") {
_cancelAccessibility();
} else if (message == "Touch") {
_touchToTheScreen();
} else if (message == "Close") {
_closeOverlay();
}
});
}
void _closeOverlay() async {
FlutterOverlayWindow.closeOverlay();
}
void _showOverlay() async {
var isEnable = await FlutterOverlayWindow.isPermissionGranted();
if (!isEnable) {
await FlutterOverlayWindow.requestPermission();
return;
}
if (await FlutterOverlayWindow.isActive()) return;
await FlutterOverlayWindow.showOverlay(
enableDrag: true,
overlayTitle: "demo",
overlayContent: 'demo',
flag: OverlayFlag.focusPointer,
visibility: NotificationVisibility.visibilityPublic,
positionGravity: PositionGravity.none,
alignment: OverlayAlignment.center,
height: 700,
width: 200,
);
}
void _sendMessageToOverlay(String message) {
homePort ??= IsolateNameServer.lookupPortByName(_kPortNameOverlay);
homePort?.send(message);
}
StreamSubscription<TouchEvent>? _subscription;
final List<TouchEvent> _events = [];
final List<TouchPoint> _touchEvents = [];
final touchService = TouchServicePlugin.defaultInstance;
void _subscribeAccessibility() async {
final isEnable = await touchService.isPermissionGranted();
if (isEnable) {
_subscription = touchService.touchStream.listen((event) {
log("$event");
setState(() {
_events.add(event);
});
});
} else {
await touchService.requestPermission();
}
}
void _setTabPosition(TapDownDetails details) {
setState(() {
_tabPositionX = details.globalPosition.dx;
_tabPositionY = details.globalPosition.dy;
});
}
void _cancelAccessibility() {
_touchEvents.clear();
_subscription?.cancel();
setState(() {
var index = 0;
for (final event in _events) {
if (index == _events.length - 1) {
break;
}
if (index == 0) {
_touchEvents.add(TouchPoint(event.x!, event.y!, 0));
} else {
_touchEvents.add(TouchPoint(event.x!, event.y!, event.time!.difference(_events[index - 1].time!).inMilliseconds));
}
index++;
}
_events.clear();
});
}
void _touchToTheScreen() async {
for (var i = 0; i < _touchEvents.length; i++) {
var touchEvent = _touchEvents[i];
await Future.delayed(Duration(milliseconds: touchEvent.delay));
await touchService.touch(Point(x: touchEvent.x, y: touchEvent.y));
}
// _touchEvents.clear();
}
void _onTouched(String text) async {
setState(() {
_text = text;
});
}
void onTabCapture() async {
await touchService.touch(Point(x: 101 * 2.5, y: 320 * 2.5));
}
void onSwipeCapture() async {
await touchService.swipe(Point(x: 201 * 2.5, y: 590 * 2.5), Point(x: 201 * 2.5, y: 320 * 2.5));
}
[@override](/user/override)
Widget build(BuildContext context) {
return GestureDetector(
onTapDown: _setTabPosition,
child: SafeArea(
child: Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
SizedBox(
height: 200,
child: Center(
child: Column(
children: [
Text('Tab position: $_tabPositionX, $_tabPositionY'),
const SizedBox(height: 8.0),
Text('Tab button: $_text'),
const SizedBox(height: 8.0),
Text('Touch events: ${_touchEvents.length}'),
const SizedBox(height: 8.0),
const TextField(
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Enter your username',
),
),
],
),
),
),
Expanded(
child: Row(
children: [
Expanded(
child: Column(
children: [
Expanded(
child: GestureDetector(
child: Center(
child: ElevatedButton(
onPressed: () {
_onTouched("button 1");
},
child: const Text('Button 1')),
),
),
),
Expanded(
child: GestureDetector(
child: Center(
child: ElevatedButton(
onPressed: () {
_onTouched("button 2");
},
child: const Text('Button 2')),
),
),
),
],
),
),
Expanded(
child: Column(
children: [
Expanded(
child: GestureDetector(
child: Center(
child: ElevatedButton(
onPressed: () {
_onTouched("button 3");
},
child: const Text('Button 3')),
),
),
),
Expanded(
child: GestureDetector(
child: Center(
child: ElevatedButton(
onPressed: onTabCapture,
child: const Text('Button 4'),
),
),
),
),
Expanded(
child: GestureDetector(
child: Center(
child: ElevatedButton(
onPressed: onSwipeCapture,
child: const Text('Button 5'),
),
),
),
),
],
),
)
],
),
),
Expanded(
flex: 2,
child: ListView.builder(
shrinkWrap: true,
itemCount: 10,
itemBuilder: (_, index) {
if (_events.length > index) {
int latestIndex = index;
return ListTile(
title: Text("event time: ${_events[latestIndex].type}-${_events[latestIndex].time!.toIso8601String()}"),
);
}
return null;
},
),
)
],
),
),
floatingActionButton: SizedBox(
height: 60,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
FloatingActionButton(
onPressed: _subscribeAccessibility,
tooltip: 'Subscribe',
child: const Icon(Icons.add),
),
const SizedBox(width: 8.0),
FloatingActionButton(
onPressed: _cancelAccessibility,
tooltip: 'Stop',
child: const Icon(Icons.stop),
),
const SizedBox(width: 8.0),
FloatingActionButton(
onPressed: _showOverlay,
tooltip: 'Overlay',
child: const Icon(Icons.play_arrow),
),
const SizedBox(width: 8.0),
FloatingActionButton(
onPressed: _closeOverlay,
tooltip: 'Close',
child: const Icon(Icons.close),
),
],
),
),
),
),
);
}
}
更多关于Flutter触摸服务插件touch_service_plugin的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter触摸服务插件touch_service_plugin的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter中,touch_service_plugin
是一个用于处理触摸事件的插件,它可以帮助你在应用程序中捕获和处理用户的触摸输入。以下是如何使用 touch_service_plugin
的基本步骤:
1. 添加依赖
首先,你需要在项目的 pubspec.yaml
文件中添加 touch_service_plugin
依赖项。
dependencies:
flutter:
sdk: flutter
touch_service_plugin: ^latest_version
然后运行 flutter pub get
来安装依赖。
2. 导入插件
在你的 Dart 文件中,导入 touch_service_plugin
。
import 'package:touch_service_plugin/touch_service_plugin.dart';
3. 初始化插件
在使用插件之前,通常需要先初始化它。
TouchServicePlugin.initialize();
4. 监听触摸事件
你可以使用 TouchServicePlugin
提供的方法来监听触摸事件。例如,你可以监听全局的触摸事件。
TouchServicePlugin.onTouchEvent.listen((TouchEvent event) {
print('Touch event detected: ${event.x}, ${event.y}');
});
TouchEvent
通常包含触摸事件的坐标 (x
, y
) 和其他相关数据。
5. 处理触摸事件
你可以根据触摸事件的内容来处理用户的输入。例如,你可以在屏幕上显示触摸点的位置。
TouchServicePlugin.onTouchEvent.listen((TouchEvent event) {
setState(() {
// 更新 UI,显示触摸点的位置
_touchX = event.x;
_touchY = event.y;
});
});
6. 停止监听
如果你不再需要监听触摸事件,可以取消监听。
TouchServicePlugin.dispose();
7. 处理权限
在某些情况下,插件可能需要特定的权限才能捕获全局触摸事件。确保你在 AndroidManifest.xml
中添加了必要的权限。
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
8. 示例代码
以下是一个完整的示例,展示如何在 Flutter 应用中使用 touch_service_plugin
。
import 'package:flutter/material.dart';
import 'package:touch_service_plugin/touch_service_plugin.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: TouchScreen(),
);
}
}
class TouchScreen extends StatefulWidget {
[@override](/user/override)
_TouchScreenState createState() => _TouchScreenState();
}
class _TouchScreenState extends State<TouchScreen> {
double _touchX = 0.0;
double _touchY = 0.0;
[@override](/user/override)
void initState() {
super.initState();
TouchServicePlugin.initialize();
TouchServicePlugin.onTouchEvent.listen((TouchEvent event) {
setState(() {
_touchX = event.x;
_touchY = event.y;
});
});
}
[@override](/user/override)
void dispose() {
TouchServicePlugin.dispose();
super.dispose();
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Touch Service Plugin Example'),
),
body: Center(
child: Text('Touch at ($_touchX, $_touchY)'),
),
);
}
}