Flutter远程控制插件flutter_remoter的使用
Flutter远程控制插件flutter_remoter的使用
特性
- 全局和单独选项
- 如果没有监听器,缓存会在缓存时间后被收集
- 如果查询过期,会重新获取数据
- 当多个小部件同时挂载时,只会获取一次数据
- 分页
- 使查询无效
- 手动设置查询数据
- 当新小部件挂载时重试查询
- 自动重试,指数退避策略
- 变更小部件
开始使用
安装依赖
在pubspec.yaml
文件中添加以下依赖:
dependencies:
flutter_remoter: ^0.2.0
包裹你的应用
包裹你的应用需要使用RemoterProvider
并传入一个RemoterClient
实例。RemoterClient
可以用于整个应用。
class MyApp extends StatelessWidget {
const MyApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return RemoterProvider(
client: RemoterClient(
// 这一行定义了所有查询的默认选项
// 您可以在每个查询中覆盖这些选项
options: RemoterOptions(
// staleTime 定义了查询获取后的多少毫秒内可以重新获取
// 使用无限的staleTime如果不需要在新的查询挂载时重新获取数据
// 1 << 31 是最大int32
// 默认是0毫秒
staleTime: 0,
// cacheTime 定义了在所有监听器消失后的多少毫秒内清除查询数据
// 默认是5分钟
cacheTime: 5 * 60 * 1000,
// 最大重试延迟(毫秒)
maxDelay: 5 * 60 * 1000,
// 最大重试次数
maxRetries: 3,
// 标志决定错误状态的查询是否在挂载时重新获取
retryOnMount: true,
),
),
child: const MaterialApp(
home: MyHomePage(),
),
);
}
}
使用
RemoterQuery
用于获取单个页面的数据。
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
body: RemoterQuery<List<String>>(
// remoterKey 应该是唯一的
remoterKey: "numbers",
execute: () async {
return List.generate(12, (index) => (index + 1).toString());
},
builder: (context, snapshot, utils) {
if (snapshot.status == RemoterStatus.idle) {
// 您可以跳过此检查如果您不使用disabled参数
}
if (snapshot.status == RemoterStatus.fetching) {
return const Center(
child: Padding(
padding: EdgeInsets.all(8.0),
child: CircularProgressIndicator(),
),
);
}
if (snapshot.status == RemoterStatus.error) {
return Container(
alignment: Alignment.center,
padding: const EdgeInsets.symmetric(vertical: 16),
child: Column(
children: [
const Text(
"Error occured",
style: TextStyle(fontWeight: FontWeight.bold),
),
ElevatedButton(
child: const Text("retry"),
onPressed: () {
utils.retry();
}),
],
),
);
}
// 这里可以安全地使用snapshot.data!
return Container(
alignment: Alignment.topCenter,
child: GridView(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
),
children: snapshot.data!
.map(
(text) => Text(
text,
textAlign: TextAlign.center,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 24,
),
),
)
.toList(),
),
);
}),
);
}
}
PaginatedRemoterQuery
用于具有多页或类似“无限滚动”的数据。
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
body: PaginatedRemoterQuery<List<String>>(
// remoterKey 应该是唯一的
remoterKey: "numbers",
getNextPageParam: (pages) {
return pages[pages.length - 1] + 1;
},
getPreviousPageParam: (pages) {
return pages[0] - 1;
},
execute: (param) async {
return List.generate(param, (index) => (index + 1).toString());
},
builder: (context, snapshot, utils) {
if (snapshot.status == RemoterStatus.idle) {
// 您可以跳过此检查如果您不使用disabled参数
}
if (snapshot.status == RemoterStatus.fetching) {
return const Center(
child: Padding(
padding: EdgeInsets.all(8.0),
child: CircularProgressIndicator(),
),
);
}
if (snapshot.status == RemoterStatus.error) {
return Container(
alignment: Alignment.center,
padding: const EdgeInsets.symmetric(vertical: 16),
child: Column(
children: [
const Text(
"Error occured",
style: TextStyle(fontWeight: FontWeight.bold),
),
ElevatedButton(
child: const Text("retry"),
onPressed: () {
utils.retry();
}),
],
),
);
}
// 这里可以安全地使用snapshot.data!
return SingleChildScrollView(
child: Column(
children: [
if (snapshot.hasPreviousPage)
ElevatedButton(
onPressed: () {
utils.fetchPreviousPage();
},
child: snapshot.isFetchingPreviousPage == true
? const CircularProgressIndicator(
color: Colors.white,
)
: const Text("Load previous"),
),
...snapshot.data!
.expand((el) => el)
.map(
(d) => Text(d),
)
.toList(),
if (snapshot.hasNextPage)
ElevatedButton(
onPressed: () {
utils.fetchNextPage();
},
child: snapshot.isFetchingNextPage == true
? const CircularProgressIndicator(
color: Colors.white,
)
: const Text("Load more"),
),
],
),
);
}),
);
}
}
RemoterMutation
用于简化处理异步调用。
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
body: RemoterMutation<String, String>(
execute: (param) async {
await Future.delayed(const Duration(seconds: 1));
return "Mutation executed with param: $param";
},
builder: (context, snapshot, utils) {
if (snapshot.status == RemoterStatus.idle) {
// Mutation hasn't started yet
}
if (snapshot.status == RemoterStatus.fetching) {
// Handle fetching state here
}
if (snapshot.status == RemoterStatus.error) {
// Handle error here
}
// It is okay to use snapshot.data! here
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
snapshot.data ?? "",
style: const TextStyle(fontSize: 24),
),
const SizedBox(height: 16),
FloatingActionButton(
onPressed: snapshot.status == RemoterStatus.fetching
? null
: () {
// Starts mutation
// In this case null will be passed to execute as param
utils.mutate("Test");
},
child: const Icon(Icons.add),
),
],
);
},
),
);
}
}
使用RemoterClient
有两种方法来获取RemoterClient
实例。
使用BuildContext
RemoterProvider.of(context).client
不使用BuildContext
为了在不使用BuildContext
的情况下使用RemoterClient
,您可以创建一个RemoterClient
实例并在单独的文件中导入它。然后将该实例传递给RemoterProvider
,这样您就可以在应用的任何地方使用它。
// 在单独的文件中创建 RemoterClient 实例
import 'path_to_RemoterClient_instance';
class MyApp extends StatelessWidget {
const MyApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return RemoterProvider(
// 'client' 是从导入的实例
client: client,
child: const MaterialApp(
home: MyHomePage(),
),
);
}
}
更多关于Flutter远程控制插件flutter_remoter的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter远程控制插件flutter_remoter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
flutter_remoter
是一个用于 Flutter 的远程控制插件,它允许你通过网络远程控制其他设备或应用。这个插件通常用于实现远程桌面、远程控制设备等功能。以下是如何使用 flutter_remoter
插件的基本步骤:
1. 添加依赖
首先,你需要在 pubspec.yaml
文件中添加 flutter_remoter
插件的依赖:
dependencies:
flutter:
sdk: flutter
flutter_remoter: ^0.1.0 # 请根据实际版本号填写
然后运行 flutter pub get
来获取依赖。
2. 导入插件
在你的 Dart 文件中导入 flutter_remoter
插件:
import 'package:flutter_remoter/flutter_remoter.dart';
3. 初始化插件
在使用插件之前,通常需要先进行初始化。你可以通过以下方式初始化 flutter_remoter
:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await FlutterRemoter.initialize();
runApp(MyApp());
}
4. 创建远程控制连接
你可以通过 FlutterRemoter
类来创建一个远程控制连接。假设你有一个服务器地址和端口,你可以这样连接:
Future<void> connectToRemote() async {
try {
await FlutterRemoter.connect('192.168.1.100', 8080);
print('Connected to remote device');
} catch (e) {
print('Failed to connect: $e');
}
}
5. 发送控制命令
连接成功后,你可以发送控制命令到远程设备。例如,发送一个鼠标点击事件:
void sendMouseClick() {
FlutterRemoter.sendMouseEvent(100, 100, MouseEventType.click);
}
6. 处理远程事件
你还可以监听来自远程设备的事件。例如,监听键盘输入:
void listenToKeyboardEvents() {
FlutterRemoter.onKeyboardEvent.listen((event) {
print('Key pressed: ${event.key}');
});
}
7. 断开连接
当你不再需要远程控制时,可以断开连接:
void disconnect() async {
await FlutterRemoter.disconnect();
print('Disconnected from remote device');
}
8. 示例代码
以下是一个简单的示例代码,展示了如何使用 flutter_remoter
插件进行远程控制:
import 'package:flutter/material.dart';
import 'package:flutter_remoter/flutter_remoter.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await FlutterRemoter.initialize();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Flutter Remoter Example')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: connectToRemote,
child: Text('Connect to Remote'),
),
ElevatedButton(
onPressed: sendMouseClick,
child: Text('Send Mouse Click'),
),
ElevatedButton(
onPressed: disconnect,
child: Text('Disconnect'),
),
],
),
),
),
);
}
Future<void> connectToRemote() async {
try {
await FlutterRemoter.connect('192.168.1.100', 8080);
print('Connected to remote device');
} catch (e) {
print('Failed to connect: $e');
}
}
void sendMouseClick() {
FlutterRemoter.sendMouseEvent(100, 100, MouseEventType.click);
}
void disconnect() async {
await FlutterRemoter.disconnect();
print('Disconnected from remote device');
}
}