Compare commits
13 Commits
0.0.5
...
e6c63982a0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e6c63982a0 | ||
|
|
b57f043875 | ||
|
|
9007b717ce | ||
|
|
f51c64c9a2 | ||
|
|
c8924ee3ed | ||
|
|
9545928a35 | ||
|
|
95e5c65709 | ||
|
|
d6d83fbc46 | ||
|
|
63b38704dc | ||
|
|
587af2c22a | ||
|
|
cbd3d8eff8 | ||
|
|
20f557c668 | ||
|
|
e54e11fef1 |
146
README.md
146
README.md
@@ -51,18 +51,17 @@ bridge.share(
|
||||
);
|
||||
```
|
||||
|
||||
### 监听来自 Flutter 的消息
|
||||
## 示例页面
|
||||
|
||||
```dart
|
||||
// 注册监听器
|
||||
FlutterBridge.instance.on(FromFlutterAppEnum.translateResult.code, (data) {
|
||||
print("收到翻译结果: ${data['data']}");
|
||||
// 处理翻译结果
|
||||
});
|
||||
包中包含了一个完整的示例页面 `WebToolsExamplePage`,展示了所有交互方法的使用示例,按功能模块分类组织。
|
||||
|
||||
// 使用完毕后记得取消监听
|
||||
FlutterBridge.instance.off(FromFlutterAppEnum.translateResult.code);
|
||||
### 使用示例页面
|
||||
```agsl
|
||||
在自己的web项目中 添加测试跳转连接
|
||||
Get.to(WebToolsExamplePage());
|
||||
```
|
||||

|
||||
|
||||
|
||||
## API 文档
|
||||
|
||||
@@ -76,28 +75,42 @@ FlutterBridge.instance.off(FromFlutterAppEnum.translateResult.code);
|
||||
final bridge = FlutterBridge.instance;
|
||||
```
|
||||
|
||||
#### 消息监听方法
|
||||
|
||||
### 监听来自 Flutter 的消息 (支持一对多监听)
|
||||
### 不走队列。这是“广播”模式
|
||||
##### `on(String type, Function(Map<String, dynamic>) callback)`
|
||||
|
||||
注册一个消息监听器。
|
||||
注册一个消息监听器。现在支持为同一 `type` 注册多个监听器。
|
||||
|
||||
- `type`: 消息类型(使用 `FromFlutterAppEnum` 中的 code)
|
||||
- `callback`: 回调函数,接收消息数据
|
||||
|
||||
**返回** `VoidCallback`: 调用此函数可以精确地移除当前注册的这个监听器。
|
||||
|
||||
```dart
|
||||
bridge.on(FromFlutterAppEnum.translateResult.code, (data) {
|
||||
// 处理消息
|
||||
// 注册第一个监听器
|
||||
final cancelListener1 = bridge.on(FromFlutterAppEnum.translateResult.code, (data) {
|
||||
print("监听器1收到翻译结果: ${data['data']}");
|
||||
});
|
||||
|
||||
// 注册第二个监听器
|
||||
final cancelListener2 = bridge.on(FromFlutterAppEnum.translateResult.code, (data) {
|
||||
print("监听器2收到翻译结果: ${data['data']}");
|
||||
});
|
||||
|
||||
// 当不再需要第一个监听器时,调用其返回的函数
|
||||
cancelListener1.call();// 仅移除监听器1
|
||||
// 当不再需要第二个监听器时,调用其返回的函数
|
||||
cancelListener2.call();// 仅移除监听器2
|
||||
```
|
||||
|
||||
##### `off(String type)`
|
||||
|
||||
取消注册消息监听器。
|
||||
取消注册某个 `type` 的【所有】消息监听器。此方法主要用于需要一次性清空所有同类型监听的场景。
|
||||
|
||||
- `type`: 要取消监听的消息类型
|
||||
- `type`: 要取消监听的【所有】消息类型
|
||||
|
||||
```dart
|
||||
// 警告:这将移除 FromFlutterAppEnum.translateResult.code 对应的所有监听器
|
||||
bridge.off(FromFlutterAppEnum.translateResult.code);
|
||||
```
|
||||
|
||||
@@ -178,14 +191,22 @@ bridge.share(
|
||||
);
|
||||
```
|
||||
|
||||
##### 翻译功能
|
||||
|
||||
##### 翻译功能(发送翻译消息+监听返回结果)
|
||||
##### 只有当你调用 sendRequest 方法时,才会走队列
|
||||
```dart
|
||||
bridge.translateRequest({
|
||||
'text': 'Hello',
|
||||
'from': 'en',
|
||||
'to': 'zh',
|
||||
});
|
||||
bridge.sendRequest(
|
||||
sendType: ToFlutterAppEnum.translateRequest, // 1. 发送类型
|
||||
listenType: FromFlutterAppEnum.translateResult, // 2. 监听类型
|
||||
params: {
|
||||
'text00001': 'text00001',
|
||||
'text00002': 'text00002',
|
||||
'text00003': 'text00003',
|
||||
}, // 3. 参数
|
||||
onSuccess: (data) {
|
||||
// 4. 成功回调 (自动排队,安全)
|
||||
print("翻译结果: $data");
|
||||
},
|
||||
);
|
||||
```
|
||||
|
||||
##### 直播间相关
|
||||
@@ -274,27 +295,28 @@ Flutter 向 H5 发送的消息类型枚举。包含:
|
||||
```dart
|
||||
import 'package:web_tools/web_tools.dart';
|
||||
|
||||
//需要翻译的map
|
||||
var textMap = <String, String>{};
|
||||
|
||||
void setupTranslation() {
|
||||
final bridge = FlutterBridge.instance;
|
||||
// 使用 sendRequest (发送请求并队列监听回调,内部自动释放监听回调),该方法只监听一次,
|
||||
// 如果需要多次监听,请使用 FlutterBridge.instance.on,并且手动释放监听回调
|
||||
FlutterBridge.instance.sendRequest(
|
||||
sendType: ToFlutterAppEnum.translateRequest, // 1. 发送类型
|
||||
listenType: FromFlutterAppEnum.translateResult, // 2. 监听类型
|
||||
params: textMap, // 3. 参数
|
||||
onSuccess: (data) {
|
||||
// 4. 成功回调 (自动排队,安全)
|
||||
print("翻译结果: $data");
|
||||
|
||||
// 注册翻译结果监听器
|
||||
bridge.on(FromFlutterAppEnum.translateResult.code, (data) {
|
||||
final translatedText = data['data']['text'];
|
||||
print('翻译结果: $translatedText');
|
||||
// 更新 UI 显示翻译结果
|
||||
});
|
||||
final Map<String, String> result =
|
||||
data.map((key, value) => MapEntry(key, value.toString()));
|
||||
|
||||
// 发送翻译请求
|
||||
bridge.translateRequest({
|
||||
'text': 'Hello World',
|
||||
'from': 'en',
|
||||
'to': 'zh',
|
||||
});
|
||||
}
|
||||
|
||||
void cleanup() {
|
||||
// 清理监听器
|
||||
FlutterBridge.instance.off(FromFlutterAppEnum.translateResult.code);
|
||||
textMap.clear();// 清空临时变量
|
||||
FlutterBridge.instance.textMap.addAll(translated);//全局变量追加翻译结果
|
||||
update(['your_id']);
|
||||
},
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
@@ -303,29 +325,51 @@ void cleanup() {
|
||||
```dart
|
||||
import 'package:web_tools/web_tools.dart';
|
||||
|
||||
void setupShare() {
|
||||
final bridge = FlutterBridge.instance;
|
||||
class SantaLogic extends GetxController {
|
||||
|
||||
// 注册分享完成监听器
|
||||
bridge.on(FromFlutterAppEnum.shareFinished.code, (data) {
|
||||
print('分享完成');
|
||||
// 处理分享完成后的逻辑
|
||||
});
|
||||
// 1. 定义一个变量来持有取消函数
|
||||
VoidCallback? _cancelShareListener;
|
||||
|
||||
// 触发分享
|
||||
bridge.share(
|
||||
@override
|
||||
void onReady() {
|
||||
super.onReady();
|
||||
|
||||
// 2. 注册监听(需要监听分享回调时)
|
||||
// on 方法现在会返回一个取消函数,专门用来取消“这一个”监听
|
||||
_cancelShareListener = FlutterBridge.instance.on(
|
||||
FromFlutterAppEnum.shareFinished.code,
|
||||
(data) {
|
||||
print("SantaLogic: 收到分享成功的广播");
|
||||
// 执行业务,比如刷新任务列表
|
||||
requestTaskInfo();
|
||||
}
|
||||
);
|
||||
// 1. 触发分享(有些分享不需要监听,只需要触发分享)
|
||||
FlutterBridge.instance.share(
|
||||
activityId: 'activity_123',
|
||||
needShareReport: true,
|
||||
extraParams: {'source': 'web'},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
// 3. ⚠️⚠️⚠️ 如果注册了监听,必须在页面销毁时调用取消函数
|
||||
// 如果不调用,SantaLogic 即使退出了,这个闭包还在 Bridge 里,
|
||||
// 下次分享成功时,代码还会跑,且 SantaLogic 无法被垃圾回收!
|
||||
_cancelShareListener?.call();
|
||||
|
||||
super.onClose();
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **单例模式**:`FlutterBridge` 使用单例模式,在整个应用中只有一个实例。
|
||||
|
||||
2. **监听器管理**:使用 `on()` 注册的监听器在使用完毕后应该使用 `off()` 取消注册,避免内存泄漏。
|
||||
2. **监听器管理**:使用 `on()` 注册的监听器在使用完毕后必须使用`_listener1.call()` 取消注册,避免内存泄漏, `off()` 慎用,这将移除对应type的所有监听器。`sendRequest()`方法是融合了发送消息+监听回调,不用手动取消监听,内部自动清理监听。并且只监听一次,防止多次回调。
|
||||
|
||||
3. **消息格式**:所有消息都遵循 `{'type': '消息类型', 'data': {...}}` 的格式。
|
||||
|
||||
|
||||
695
lib/example_page.dart
Normal file
695
lib/example_page.dart
Normal file
@@ -0,0 +1,695 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:web_tools/web_tools.dart';
|
||||
|
||||
class WebToolsExamplePage extends StatefulWidget {
|
||||
const WebToolsExamplePage({super.key});
|
||||
|
||||
@override
|
||||
State<WebToolsExamplePage> createState() => _WebToolsExamplePageState();
|
||||
}
|
||||
|
||||
class _WebToolsExamplePageState extends State<WebToolsExamplePage> {
|
||||
final FlutterBridge bridge = FlutterBridge.instance;
|
||||
|
||||
// 控制器用于输入参数
|
||||
final TextEditingController gameIdController = TextEditingController()
|
||||
..text = '311';
|
||||
final TextEditingController userIdController = TextEditingController()
|
||||
..text = 'f894609cbab2440c8b2c5161049ec881';
|
||||
final TextEditingController googleProductIdController =
|
||||
TextEditingController()..text = '70055';
|
||||
final TextEditingController iosProductIdController = TextEditingController();
|
||||
final TextEditingController pathController = TextEditingController();
|
||||
final TextEditingController titleController = TextEditingController();
|
||||
final TextEditingController gameCodeController = TextEditingController()
|
||||
..text = '310';
|
||||
final TextEditingController activityIdController = TextEditingController()
|
||||
..text = '83';
|
||||
final TextEditingController schemeController = TextEditingController();
|
||||
final TextEditingController linkUrlController = TextEditingController();
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
gameIdController.dispose();
|
||||
userIdController.dispose();
|
||||
googleProductIdController.dispose();
|
||||
iosProductIdController.dispose();
|
||||
pathController.dispose();
|
||||
titleController.dispose();
|
||||
gameCodeController.dispose();
|
||||
activityIdController.dispose();
|
||||
schemeController.dispose();
|
||||
linkUrlController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Widget _buildMethodTile(
|
||||
String title, String description, VoidCallback onPressed) {
|
||||
return ListTile(
|
||||
title: Text(title, style: const TextStyle(fontWeight: FontWeight.bold)),
|
||||
subtitle: Text(description),
|
||||
trailing: ElevatedButton(
|
||||
onPressed: onPressed,
|
||||
child: const Text('调用'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildMethodWithInputTile(
|
||||
String title,
|
||||
String description,
|
||||
TextEditingController controller,
|
||||
String hint,
|
||||
VoidCallback onPressed,
|
||||
) {
|
||||
return ListTile(
|
||||
title: Text(title, style: const TextStyle(fontWeight: FontWeight.bold)),
|
||||
subtitle: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(description),
|
||||
const SizedBox(height: 8),
|
||||
TextField(
|
||||
controller: controller,
|
||||
decoration: InputDecoration(
|
||||
hintText: hint,
|
||||
border: const OutlineInputBorder(),
|
||||
contentPadding:
|
||||
const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
trailing: ElevatedButton(
|
||||
onPressed: onPressed,
|
||||
child: const Text('调用'),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Web Tools 交互方法示例'),
|
||||
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
|
||||
),
|
||||
body: ListView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
children: [
|
||||
// 游戏相关模块
|
||||
ExpansionTile(
|
||||
title: const Text('游戏相关方法'),
|
||||
children: [
|
||||
_buildMethodTile(
|
||||
'关闭页面',
|
||||
'关闭当前网页',
|
||||
() => bridge.close(),
|
||||
),
|
||||
_buildMethodTile(
|
||||
'关闭游戏页面',
|
||||
'关闭游戏页面左上角返回',
|
||||
() => bridge.sendToFlutter(ToFlutterAppEnum.gameExit.code, {}),
|
||||
),
|
||||
_buildMethodTile(
|
||||
'游戏结束',
|
||||
'通知原生游戏已结束',
|
||||
() => bridge.gameOver(),
|
||||
),
|
||||
_buildMethodWithInputTile(
|
||||
'创建游戏',
|
||||
'创建指定ID的游戏',
|
||||
gameIdController,
|
||||
'输入游戏ID',
|
||||
() {
|
||||
if (gameIdController.text.isNotEmpty) {
|
||||
bridge.createGame(gameIdController.text);
|
||||
} else {
|
||||
bridge.createGame("311");
|
||||
}
|
||||
},
|
||||
),
|
||||
_buildMethodWithInputTile(
|
||||
'想玩游戏',
|
||||
'表达想玩指定游戏的意愿',
|
||||
gameIdController,
|
||||
'输入游戏ID',
|
||||
() {
|
||||
if (gameIdController.text.isNotEmpty) {
|
||||
bridge.wantToPlay(gameIdController.text);
|
||||
}
|
||||
},
|
||||
),
|
||||
_buildMethodWithInputTile(
|
||||
'跳转到游戏详情页',
|
||||
'不同的值代表不同的游戏',
|
||||
gameIdController,
|
||||
'gameType',
|
||||
() {
|
||||
if (gameIdController.text.isNotEmpty) {
|
||||
bridge.sendToFlutter(ToFlutterAppEnum.gameType.code,
|
||||
{"gameType": gameIdController.text});
|
||||
}
|
||||
},
|
||||
),
|
||||
_buildMethodWithInputTile(
|
||||
'检查游戏状态',
|
||||
'检查指定游戏的状态',
|
||||
gameCodeController,
|
||||
'输入游戏代码',
|
||||
() {
|
||||
if (gameCodeController.text.isNotEmpty) {
|
||||
bridge.checkGameState(gameCodeController.text);
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
// 充值支付模块
|
||||
ExpansionTile(
|
||||
title: const Text('充值支付方法'),
|
||||
children: [
|
||||
_buildMethodTile(
|
||||
'前往充值',
|
||||
'跳转到充值页面',
|
||||
() => bridge.toRecharge(),
|
||||
),
|
||||
_buildMethodTile(
|
||||
'前往红钻充值',
|
||||
'跳转到红钻充值页面',
|
||||
() => bridge.toRedDiamond(),
|
||||
),
|
||||
_buildMethodTile(
|
||||
'定向充值',
|
||||
'直接唤起内购付费框',
|
||||
() => bridge.sendToFlutter(
|
||||
ToFlutterAppEnum.rechargeItem.code, {"productId": "70055"}),
|
||||
),
|
||||
ListTile(
|
||||
title: const Text('月卡支付',
|
||||
style: TextStyle(fontWeight: FontWeight.bold)),
|
||||
subtitle: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text('跳转到月卡支付页面'),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: TextField(
|
||||
controller: googleProductIdController,
|
||||
decoration: const InputDecoration(
|
||||
hintText: 'Google产品ID',
|
||||
border: OutlineInputBorder(),
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
horizontal: 12, vertical: 8),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
controller: iosProductIdController,
|
||||
decoration: const InputDecoration(
|
||||
hintText: 'iOS产品ID',
|
||||
border: OutlineInputBorder(),
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
horizontal: 12, vertical: 8),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
TextField(
|
||||
controller: userIdController,
|
||||
decoration: const InputDecoration(
|
||||
hintText: '其他用户ID (可选)',
|
||||
border: OutlineInputBorder(),
|
||||
contentPadding:
|
||||
EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
trailing: ElevatedButton(
|
||||
onPressed: () {
|
||||
if (googleProductIdController.text.isNotEmpty &&
|
||||
iosProductIdController.text.isNotEmpty) {
|
||||
bridge.toMonthCardPay(
|
||||
googleProductIdController.text,
|
||||
iosProductIdController.text,
|
||||
otherUserId: userIdController.text,
|
||||
);
|
||||
}
|
||||
},
|
||||
child: const Text('调用'),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
// 页面导航模块
|
||||
ExpansionTile(
|
||||
title: const Text('页面导航方法'),
|
||||
children: [
|
||||
ListTile(
|
||||
title: const Text('跳转到H5页面',
|
||||
style: TextStyle(fontWeight: FontWeight.bold)),
|
||||
subtitle: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text('在原生App中跳转到H5页面'),
|
||||
const SizedBox(height: 8),
|
||||
TextField(
|
||||
controller: pathController,
|
||||
decoration: const InputDecoration(
|
||||
hintText: '页面路径',
|
||||
border: OutlineInputBorder(),
|
||||
contentPadding:
|
||||
EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
TextField(
|
||||
controller: titleController,
|
||||
decoration: const InputDecoration(
|
||||
hintText: '页面标题',
|
||||
border: OutlineInputBorder(),
|
||||
contentPadding:
|
||||
EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
trailing: ElevatedButton(
|
||||
onPressed: () {
|
||||
if (pathController.text.isNotEmpty &&
|
||||
titleController.text.isNotEmpty) {
|
||||
bridge.jumpToH5(
|
||||
pathController.text, titleController.text);
|
||||
}
|
||||
},
|
||||
child: const Text('调用'),
|
||||
),
|
||||
),
|
||||
_buildMethodWithInputTile(
|
||||
'前往用户主页',
|
||||
'跳转到指定用户的主页',
|
||||
userIdController,
|
||||
'输入用户ID',
|
||||
() {
|
||||
if (userIdController.text.isNotEmpty) {
|
||||
bridge.toHomepage(userIdController.text);
|
||||
}
|
||||
},
|
||||
),
|
||||
_buildMethodTile("恩爱节活动", "恩爱节活动跳转选择好友 1:cp 2:告白 3:组队", () {
|
||||
bridge.sendToFlutter(
|
||||
ToFlutterAppEnum.lovingDayChooseFriend.code, {});
|
||||
}),
|
||||
ListTile(
|
||||
title: const Text('跳转到网页',
|
||||
style: TextStyle(fontWeight: FontWeight.bold)),
|
||||
subtitle: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text('在原生App中打开网页'),
|
||||
const SizedBox(height: 8),
|
||||
TextField(
|
||||
controller: linkUrlController,
|
||||
decoration: const InputDecoration(
|
||||
hintText: '网页链接',
|
||||
border: OutlineInputBorder(),
|
||||
contentPadding:
|
||||
EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
TextField(
|
||||
controller: activityIdController,
|
||||
decoration: const InputDecoration(
|
||||
hintText: '活动ID',
|
||||
border: OutlineInputBorder(),
|
||||
contentPadding:
|
||||
EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
trailing: ElevatedButton(
|
||||
onPressed: () {
|
||||
if (linkUrlController.text.isNotEmpty &&
|
||||
activityIdController.text.isNotEmpty) {
|
||||
bridge.taskToWebViewPage(
|
||||
linkUrl: linkUrlController.text,
|
||||
activityId: activityIdController.text,
|
||||
);
|
||||
}
|
||||
},
|
||||
child: const Text('调用'),
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
title: const Text('解析URL并跳转',
|
||||
style: TextStyle(fontWeight: FontWeight.bold)),
|
||||
subtitle: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text('解析scheme URL并跳转'),
|
||||
const SizedBox(height: 8),
|
||||
TextField(
|
||||
controller: schemeController,
|
||||
decoration: const InputDecoration(
|
||||
hintText: 'Scheme URL',
|
||||
border: OutlineInputBorder(),
|
||||
contentPadding:
|
||||
EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
TextField(
|
||||
controller: activityIdController,
|
||||
decoration: const InputDecoration(
|
||||
hintText: '活动ID',
|
||||
border: OutlineInputBorder(),
|
||||
contentPadding:
|
||||
EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
trailing: ElevatedButton(
|
||||
onPressed: () {
|
||||
if (schemeController.text.isNotEmpty &&
|
||||
activityIdController.text.isNotEmpty) {
|
||||
bridge.taskCommandJump(
|
||||
scheme: schemeController.text,
|
||||
activityId: activityIdController.text,
|
||||
);
|
||||
}
|
||||
},
|
||||
child: const Text('调用'),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
// 分享功能模块
|
||||
ExpansionTile(
|
||||
title: const Text('分享功能'),
|
||||
children: [
|
||||
_buildMethodWithInputTile(
|
||||
'分享(通用分享)',
|
||||
'分享活动,需要活动ID',
|
||||
activityIdController,
|
||||
'输入活动ID',
|
||||
() {
|
||||
if (activityIdController.text.isNotEmpty) {
|
||||
bridge.share(
|
||||
activityId: activityIdController.text,
|
||||
needShareReport: true,
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
_buildMethodWithInputTile(
|
||||
'分享(带卡片分享)',
|
||||
'分享活动,需要活动ID',
|
||||
activityIdController,
|
||||
'输入活动ID',
|
||||
() {
|
||||
if (activityIdController.text.isNotEmpty) {
|
||||
bridge.share(
|
||||
activityId: activityIdController.text,
|
||||
needShareReport: true,
|
||||
shareCardModel: ShareCardModel(
|
||||
activityIcon:
|
||||
"app/img/local/new_year_share_content_bg_en_th.webp",
|
||||
activityDesc: "这只是一个示例"));
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
// 直播互动模块
|
||||
ExpansionTile(
|
||||
title: const Text('直播互动方法'),
|
||||
children: [
|
||||
_buildMethodTile(
|
||||
'检查开播',
|
||||
'检查是否可以开始直播',
|
||||
() => bridge.checkStartBroadcaster(),
|
||||
),
|
||||
_buildMethodTile(
|
||||
'直播间发言任务',
|
||||
'触发直播间发言任务',
|
||||
() => bridge.taskLiveRoomChat(),
|
||||
),
|
||||
_buildMethodTile(
|
||||
'直播间送礼任务',
|
||||
'触发直播间送礼任务',
|
||||
() => bridge.taskLiveRoomGift(),
|
||||
),
|
||||
_buildMethodTile(
|
||||
'直播间其他任务',
|
||||
'触发直播间其他任务',
|
||||
() => bridge.taskLiveRoomOther(),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
// 任务系统模块
|
||||
ExpansionTile(
|
||||
title: const Text('任务系统方法'),
|
||||
children: [
|
||||
_buildMethodTile(
|
||||
'完善个人信息',
|
||||
'跳转到完善个人信息页面',
|
||||
() => bridge.shouldCompleteProfile(),
|
||||
),
|
||||
_buildMethodTile(
|
||||
'观看时长任务',
|
||||
'触发观看时长任务',
|
||||
() => bridge.shouldWatchDuration(),
|
||||
),
|
||||
_buildMethodTile(
|
||||
'发送公屏消息任务',
|
||||
'触发发送公屏消息任务',
|
||||
() => bridge.shouldSendPublicMessage(),
|
||||
),
|
||||
_buildMethodTile(
|
||||
'上麦互动任务',
|
||||
'触发上麦互动任务',
|
||||
() => bridge.shouldMicInteraction(),
|
||||
),
|
||||
_buildMethodTile(
|
||||
'发送私聊消息任务',
|
||||
'触发发送私聊消息任务',
|
||||
() => bridge.shouldSendPrivateMessage(),
|
||||
),
|
||||
_buildMethodTile(
|
||||
'发布动态任务',
|
||||
'触发发布动态任务',
|
||||
() => bridge.shouldPostFeed(),
|
||||
),
|
||||
_buildMethodTile(
|
||||
'分享房间任务',
|
||||
'触发分享房间任务',
|
||||
() => bridge.shouldShareRoom(),
|
||||
),
|
||||
_buildMethodTile(
|
||||
'佩戴装扮任务',
|
||||
'触发佩戴装扮任务',
|
||||
() => bridge.shouldWearDecoration(),
|
||||
),
|
||||
_buildMethodTile(
|
||||
'前往语音房任务',
|
||||
'触发前往语音房任务',
|
||||
() => bridge.shouldGoToVoiceRoom(),
|
||||
),
|
||||
_buildMethodTile(
|
||||
'观看直播',
|
||||
'触发前往语音房任务有-》 收藏房间 | 关注主播 | 发送房间消息 ',
|
||||
() => bridge.commonInteraction({
|
||||
"interactionType": WebInteractionType.taskKeyWatchLive.code,
|
||||
// taskKeyCollectRoom | taskKeyFollowUser | taskKeySendRoomMessage
|
||||
}),
|
||||
),
|
||||
_buildMethodTile(
|
||||
'赠送礼物',
|
||||
'触发前往语音房任务 && (打开礼物面板 or 赠送指定礼物 or 打开我的背包) ',
|
||||
() => bridge.commonInteraction({
|
||||
"interactionType": WebInteractionType.taskKeySendGift
|
||||
.code, // taskKeySendGiftId | taskKeySendBackpackGift
|
||||
...{"targetId": ""}
|
||||
}),
|
||||
),
|
||||
_buildMethodTile(
|
||||
'我想玩 XX游戏',
|
||||
'触发前往语音房任务 && 发送我想玩 XX游戏',
|
||||
() => bridge.commonInteraction({
|
||||
"interactionType": WebInteractionType
|
||||
.taskKeyPlayGame.code, // taskKeySendGiftId
|
||||
...{"targetId": ""}
|
||||
}),
|
||||
),
|
||||
_buildMethodTile(
|
||||
'发红包',
|
||||
'触发前往语音房任务 && 发红包',
|
||||
() => bridge.commonInteraction({
|
||||
"interactionType": "TaskKeySendRedPack",
|
||||
}),
|
||||
),
|
||||
_buildMethodTile(
|
||||
'发送私聊消息',
|
||||
'聊天 Tab ',
|
||||
() => bridge.commonInteraction({
|
||||
"interactionType": WebInteractionType
|
||||
.taskKeySendPrivateMessage.code, // taskKeySendGiftId
|
||||
}),
|
||||
),
|
||||
_buildMethodTile(
|
||||
'参与动态话题',
|
||||
'比传参数 topicTitle',
|
||||
() => bridge.commonInteraction({
|
||||
"interactionType":
|
||||
WebInteractionType.taskKeyTimelineTopic.code,
|
||||
...{
|
||||
"topicTitle": "",
|
||||
"targetId": "",
|
||||
"content": "",
|
||||
"image": "",
|
||||
"textId": ""
|
||||
}
|
||||
// taskKeySendGiftId
|
||||
}),
|
||||
),
|
||||
_buildMethodTile(
|
||||
'点赞动态 or 评论动态',
|
||||
'切换 圈子 Tab',
|
||||
() => bridge.commonInteraction({
|
||||
"interactionType": WebInteractionType
|
||||
.taskKeyLikeTimeline.code, // taskKeyReplayTimeline
|
||||
}),
|
||||
),
|
||||
_buildMethodTile(
|
||||
'签到',
|
||||
'首页签到弹框',
|
||||
() => bridge.commonInteraction({
|
||||
"interactionType": WebInteractionType
|
||||
.taskKeySignIn.code, // taskKeyReplayTimeline
|
||||
|
||||
// taskKeySendGiftId
|
||||
}),
|
||||
),
|
||||
_buildMethodTile(
|
||||
'其他页面',
|
||||
'进入其他h5页面',
|
||||
() => bridge.commonInteraction({
|
||||
"interactionType": WebInteractionType
|
||||
.taskKeyOtherPage.code, // taskKeyReplayTimeline
|
||||
|
||||
// taskKeySendGiftId
|
||||
}),
|
||||
),
|
||||
_buildMethodTile(
|
||||
'我的钱包页面',
|
||||
'我的钱包页面',
|
||||
() => bridge.commonInteraction({
|
||||
"interactionType": WebInteractionType
|
||||
.taskKeyMineWallet.code, // taskKeyReplayTimeline
|
||||
|
||||
// taskKeySendGiftId
|
||||
}),
|
||||
),
|
||||
_buildMethodTile(
|
||||
'我的背包',
|
||||
'我的装扮背包页面(或者是称号)',
|
||||
() => bridge.commonInteraction({
|
||||
"interactionType": WebInteractionType
|
||||
.taskKeyMineBackpack.code, // taskKeyReplayTimeline
|
||||
|
||||
// taskKeySendGiftId
|
||||
}),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
// 其他功能模块
|
||||
ExpansionTile(
|
||||
title: const Text('其他功能方法'),
|
||||
children: [
|
||||
_buildMethodTile(
|
||||
'专属见面礼',
|
||||
'触发专属见面礼任务',
|
||||
() => bridge.taskInviteCodeGift(),
|
||||
),
|
||||
_buildMethodTile(
|
||||
'跳转从业者申请',
|
||||
'跳转到从业者申请页面',
|
||||
() => bridge.toApplyAdmissionPage(),
|
||||
),
|
||||
_buildMethodTile(
|
||||
'直播预约设置',
|
||||
'打开直播预约设置',
|
||||
() => bridge.shouLiveBookingPicker(),
|
||||
),
|
||||
_buildMethodTile(
|
||||
'观时礼刷新宝箱数据',
|
||||
'观时礼刷新宝箱数据',
|
||||
() =>
|
||||
bridge.sendToFlutter(ToFlutterAppEnum.closeObserving.code, {
|
||||
"updateType": "1" // 1 刷新整个挂件数据,2刷新观时礼的宝箱列表数据
|
||||
}),
|
||||
),
|
||||
_buildMethodTile(
|
||||
'翻译',
|
||||
'多语言翻译',
|
||||
() => bridge.sendRequest(
|
||||
sendType: ToFlutterAppEnum.translateRequest,
|
||||
listenType: FromFlutterAppEnum.translateResult,
|
||||
params: {"text0001": "text0001"},
|
||||
onSuccess: (dic) {}),
|
||||
),
|
||||
ListTile(
|
||||
title: const Text('通用交互',
|
||||
style: TextStyle(fontWeight: FontWeight.bold)),
|
||||
subtitle: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text('通用交互方法,可以传递自定义参数'),
|
||||
const SizedBox(height: 8),
|
||||
Container(
|
||||
padding: const EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: Colors.grey),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: const Text(
|
||||
'示例参数:{"action": "custom_action", "data": "value"}',
|
||||
style: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
trailing: ElevatedButton(
|
||||
onPressed: () {
|
||||
bridge.commonInteraction({
|
||||
"action": "custom_action",
|
||||
"data": "example_value",
|
||||
"timestamp": DateTime.now().toIso8601String(),
|
||||
});
|
||||
},
|
||||
child: const Text('调用'),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -4,10 +4,12 @@ import 'dart:html' as html;
|
||||
|
||||
import 'package:js/js.dart';
|
||||
import 'package:web_tools/utils/model/model.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
// h5交互通知 原生 {type:'enum',data:'所需参数,可无'}
|
||||
enum ToFlutterAppEnum {
|
||||
close('close'),
|
||||
reload('reload'), // 刷新
|
||||
gameExit('gameExit'),
|
||||
createGame('createGame'),
|
||||
wantToPlay('wantToPlay'),
|
||||
@@ -57,6 +59,13 @@ enum ToFlutterAppEnum {
|
||||
//前往语音房
|
||||
shouldGoToVoiceRoom('shouldGoToVoiceRoom'),
|
||||
|
||||
// 恩爱节活动跳转选择好友
|
||||
lovingDayChooseFriend('lovingDayChooseFriend'),
|
||||
// 恩爱节我的邀请页面
|
||||
lovingDayMyInvite('lovingDayMyInvite'),
|
||||
// 常驻cp活动规则页面
|
||||
taskKeyToCPRule('taskKeyToCPRule'),
|
||||
|
||||
// 定向充值
|
||||
rechargeItem('rechargeItem'),
|
||||
//专属见面礼
|
||||
@@ -105,12 +114,9 @@ enum WebInteractionType {
|
||||
taskKeyOtherPage('TaskKeyOtherPage'), // 其他页面
|
||||
taskKeyMineBackpack('TaskKeyMineBackpack'), // 我的装扮背包页面(或者是称号)
|
||||
taskKeyMineWallet('TaskKeyMineWallet'), // 我的钱包页面
|
||||
unknown('unknown'),
|
||||
;
|
||||
unknown('unknown');
|
||||
|
||||
const WebInteractionType(
|
||||
this.code,
|
||||
);
|
||||
const WebInteractionType(this.code);
|
||||
final String code; //服务端 key
|
||||
|
||||
factory WebInteractionType.fromCode(String? code) => values.firstWhere(
|
||||
@@ -124,6 +130,9 @@ enum FromFlutterAppEnum {
|
||||
translateResult('translateResult'), //翻译
|
||||
redDiamondRecharge('diamond_recharge'), //钻石充值
|
||||
shareFinished('share_finished'), //分享完成
|
||||
//送戒指后回调,传入type参数
|
||||
// type: 1 cp戒指赠送成功,2恩爱节告白礼物赠送成功
|
||||
cpSendRingCallBack('cp_send_ring_callback'),
|
||||
defaultCode('');
|
||||
|
||||
const FromFlutterAppEnum(this.code);
|
||||
@@ -133,22 +142,29 @@ enum FromFlutterAppEnum {
|
||||
@JS()
|
||||
external void sendMessageToNative(String data);
|
||||
|
||||
/// 🆕 [新增] 通用请求任务模型
|
||||
class _RequestTask {
|
||||
final String sendType; // 发送给 Native 的类型
|
||||
final Map<String, dynamic> params; // 发送的参数
|
||||
final Function(Map<String, dynamic>) callback; // 成功回调
|
||||
|
||||
_RequestTask(this.sendType, this.params, this.callback);
|
||||
}
|
||||
|
||||
class FlutterBridge {
|
||||
static final FlutterBridge instance = FlutterBridge._internal();
|
||||
|
||||
/**
|
||||
* 在需要处理 WebView 消息的地方注册监听器:
|
||||
* FlutterBridge.instance.on(FromJsEnum.translateResult.code, (data) {
|
||||
print("收到来自 WebView 的消息: $data");
|
||||
// 执行你需要的逻辑
|
||||
});
|
||||
使用过需要释放
|
||||
// 取消监听 'translateResult' 类型的消息
|
||||
FlutterBridge.instance.off(FromJsEnum.translateResult.code);
|
||||
* */
|
||||
final _messageListeners = <String, Function(Map<String, dynamic>)>{};
|
||||
// final _messageListeners = <String, Function(Map<String, dynamic>)>{};
|
||||
// 1. 修改这里:Value 从 Function 变成 List<Function>
|
||||
final _messageListeners = <String, List<Function(Map<String, dynamic>)>>{};
|
||||
var textMap = <String, String>{}; //多语言翻译
|
||||
|
||||
/// 🆕 [新增] 通用请求队列池 (Key: listenType, Value: 任务列表)
|
||||
final Map<String, List<_RequestTask>> _requestQueues = {};
|
||||
|
||||
/// 🆕 [新增] 忙碌状态池 (记录哪些 listenType 当前正在等待 Native 回复)
|
||||
final Set<String> _activeResponseTypes = {};
|
||||
|
||||
FlutterBridge._internal() {
|
||||
_initListener();
|
||||
}
|
||||
@@ -160,8 +176,19 @@ class FlutterBridge {
|
||||
try {
|
||||
final Map<String, dynamic> data = jsonDecode(event.data);
|
||||
final String? type = data['type'];
|
||||
// 找到监听列表,遍历调用
|
||||
if (type != null && _messageListeners.containsKey(type)) {
|
||||
_messageListeners[type]?.call(data);
|
||||
final listeners = _messageListeners[type];
|
||||
if (listeners != null && listeners.isNotEmpty) {
|
||||
// 使用 List.from 浅拷贝一份进行遍历,防止在回调中移除监听导致并发修改异常
|
||||
for (final callback in List.from(listeners)) {
|
||||
try {
|
||||
callback(data); // 这里的 data 是已经解析好的 Map
|
||||
} catch (e) {
|
||||
print("Error in listener callback: $e");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
print('Invalid message format from Flutter: $type');
|
||||
} catch (e) {
|
||||
@@ -170,8 +197,19 @@ class FlutterBridge {
|
||||
} else {
|
||||
try {
|
||||
final String? type = event.data['type'];
|
||||
// 找到监听列表,遍历调用
|
||||
if (type != null && _messageListeners.containsKey(type)) {
|
||||
_messageListeners[type]?.call(event.data);
|
||||
final listeners = _messageListeners[type];
|
||||
if (listeners != null && listeners.isNotEmpty) {
|
||||
// 使用 List.from 浅拷贝一份进行遍历,防止在回调中移除监听导致并发修改异常
|
||||
for (final callback in List.from(listeners)) {
|
||||
try {
|
||||
callback(event.data); // 这里的 data 是已经解析好的 Map
|
||||
} catch (e) {
|
||||
print("Error in listener callback: $e");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
print('Invalid message format from Flutter: $type');
|
||||
} catch (e) {
|
||||
@@ -181,24 +219,113 @@ class FlutterBridge {
|
||||
});
|
||||
}
|
||||
|
||||
// 注册监听某个 type 的消息
|
||||
void on(String type, Function(Map<String, dynamic>) callback) {
|
||||
if (_messageListeners.containsKey(type)) {
|
||||
print("Listener for '$type' is already registered.");
|
||||
return; // 如果已经注册了这个类型的监听器,就不再重复添加
|
||||
}
|
||||
_messageListeners[type] = callback;
|
||||
print("Listener for '$type' has been registered.");
|
||||
/// 3. 核心修改:on 方法
|
||||
/// 返回一个 VoidCallback,调用它即可取消本次监听
|
||||
VoidCallback on(String type, Function(Map<String, dynamic>) callback) {
|
||||
if (!_messageListeners.containsKey(type)) {
|
||||
_messageListeners[type] = [];
|
||||
}
|
||||
|
||||
// 取消监听某个 type 的消息
|
||||
void off(String type) {
|
||||
if (!_messageListeners.containsKey(type)) {
|
||||
print("No listener found for '$type'.");
|
||||
return; // 如果没有找到监听器,直接返回
|
||||
}
|
||||
_messageListeners[type]!.add(callback);
|
||||
print(
|
||||
"Listener added for '$type'. Total listeners: ${_messageListeners[type]!.length}",
|
||||
);
|
||||
|
||||
// 返回一个闭包,用于精确移除当前的 callback
|
||||
return () {
|
||||
if (_messageListeners.containsKey(type)) {
|
||||
_messageListeners[type]?.remove(callback);
|
||||
print(
|
||||
"One listener removed for '$type'. Remaining: ${_messageListeners[type]?.length}",
|
||||
);
|
||||
|
||||
// 如果该类型没有监听者了,可以选择清理 key
|
||||
if (_messageListeners[type]!.isEmpty) {
|
||||
_messageListeners.remove(type);
|
||||
print("Listener for '$type' has been removed.");
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// 警告:这会移除该类型下的【所有】监听器 (慎用,通常用于全局重置,一旦调用,该 type 别的地方监听器将失效)
|
||||
void off(String type) {
|
||||
if (_messageListeners.containsKey(type)) {
|
||||
_messageListeners.remove(type);
|
||||
print("All listeners for '$type' have been removed.");
|
||||
}
|
||||
}
|
||||
// =========================================================
|
||||
// 👇 🆕 [新增] 核心通用请求方法 (替代了旧的 requestTranslate)
|
||||
// =========================================================
|
||||
|
||||
/// 发送请求并等待回调 (自动排队,防并发)
|
||||
/// [sendType] 发送给 Native 的类型
|
||||
/// [listenType] 等待 Native 回复的类型
|
||||
/// [params] 参数
|
||||
/// [onSuccess] 成功回调
|
||||
void sendRequest({
|
||||
required ToFlutterAppEnum sendType,
|
||||
required FromFlutterAppEnum listenType,
|
||||
required Map<String, dynamic> params,
|
||||
required Function(Map<String, dynamic>) onSuccess,
|
||||
}) {
|
||||
final responseKey = listenType.code;
|
||||
|
||||
// 1. 初始化该类型的队列
|
||||
if (!_requestQueues.containsKey(responseKey)) {
|
||||
_requestQueues[responseKey] = [];
|
||||
}
|
||||
|
||||
// 2. 入队
|
||||
_requestQueues[responseKey]!.add(_RequestTask(
|
||||
sendType.code,
|
||||
params,
|
||||
onSuccess,
|
||||
));
|
||||
|
||||
// 3. 调度执行
|
||||
_processRequestQueue(responseKey);
|
||||
}
|
||||
|
||||
/// 🆕 [新增] 内部队列调度方法
|
||||
void _processRequestQueue(String responseKey) {
|
||||
// 如果该类型正在忙,或者队列空了,直接返回
|
||||
if (_activeResponseTypes.contains(responseKey) ||
|
||||
(_requestQueues[responseKey]?.isEmpty ?? true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 1. 标记忙碌
|
||||
_activeResponseTypes.add(responseKey);
|
||||
|
||||
// 2. 取出队首任务
|
||||
final task = _requestQueues[responseKey]!.removeAt(0);
|
||||
|
||||
// 3. 注册临时监听 (使用 on 的多播特性)
|
||||
VoidCallback? cancelRef;
|
||||
|
||||
cancelRef = on(responseKey, (data) {
|
||||
try {
|
||||
final innerData = data['data'] ?? {};
|
||||
// 执行业务回调
|
||||
task.callback(innerData);
|
||||
} catch (e) {
|
||||
print("Queue processing error: $e");
|
||||
} finally {
|
||||
// --- 任务闭环 ---
|
||||
// A. 移除当前临时监听 (不影响全局监听)
|
||||
cancelRef?.call();
|
||||
|
||||
// B. 解除忙碌状态
|
||||
_activeResponseTypes.remove(responseKey);
|
||||
|
||||
// C. 递归处理下一个任务
|
||||
_processRequestQueue(responseKey);
|
||||
}
|
||||
});
|
||||
|
||||
// 4. 发送 Native 消息
|
||||
sendToFlutter(task.sendType, task.params);
|
||||
}
|
||||
|
||||
// 发送消息给 App(通过 WebView 调用 JS 方法)
|
||||
@@ -228,28 +355,36 @@ class FlutterBridge {
|
||||
|
||||
// 具体封装的常用方法,直接发送消息给 Flutter Web
|
||||
void close() => sendToFlutter(ToFlutterAppEnum.close.code, {});
|
||||
void reload() => sendToFlutter(ToFlutterAppEnum.reload.code, {});
|
||||
void gameOver() => sendToFlutter(ToFlutterAppEnum.gameOver.code, {});
|
||||
void createGame(String gameId) =>
|
||||
sendToFlutter(ToFlutterAppEnum.createGame.code, {'gameId': gameId});
|
||||
void wantToPlay(String gameId) =>
|
||||
sendToFlutter(ToFlutterAppEnum.wantToPlay.code, {'gameId': gameId});
|
||||
void translateRequest(Map<String, String> data) =>
|
||||
sendToFlutter(ToFlutterAppEnum.translateRequest.code, data);
|
||||
// void translateRequest(Map<String, String> data) =>
|
||||
// sendToFlutter(ToFlutterAppEnum.translateRequest.code, data);//移除,建议使用sendRequest方法
|
||||
void toRecharge() => sendToFlutter(ToFlutterAppEnum.toRecharge.code, {});
|
||||
void toRedDiamond() => sendToFlutter(ToFlutterAppEnum.toRedDiamond.code, {});
|
||||
void jumpToH5(String path, String title) => sendToFlutter(
|
||||
ToFlutterAppEnum.jumpToH5.code, {'path': path, 'title': title});
|
||||
ToFlutterAppEnum.jumpToH5.code,
|
||||
{'path': path, 'title': title},
|
||||
);
|
||||
void toHomepage(String userId) =>
|
||||
sendToFlutter(ToFlutterAppEnum.toHomepage.code, {'userId': userId});
|
||||
void toMonthCardPay(String googleProductId, String iosProductId,
|
||||
{otherUserId = ''}) =>
|
||||
void toMonthCardPay(
|
||||
String googleProductId,
|
||||
String iosProductId, {
|
||||
otherUserId = '',
|
||||
}) =>
|
||||
sendToFlutter(ToFlutterAppEnum.toMonthCardPay.code, {
|
||||
'googleProductId': googleProductId,
|
||||
'iosProductId': iosProductId,
|
||||
'otherUserId': otherUserId,
|
||||
});
|
||||
void checkGameState(String gameCode) => sendToFlutter(
|
||||
ToFlutterAppEnum.checkGameState.code, {'gameCode': gameCode});
|
||||
ToFlutterAppEnum.checkGameState.code,
|
||||
{'gameCode': gameCode},
|
||||
);
|
||||
|
||||
void share({
|
||||
required String activityId, // 活动id
|
||||
@@ -268,14 +403,20 @@ class FlutterBridge {
|
||||
|
||||
//解析 URL 并跳转
|
||||
void taskCommandJump({required String scheme, required String activityId}) =>
|
||||
sendToFlutter(ToFlutterAppEnum.showCommandJump.code,
|
||||
{"scheme": scheme, "activityId": activityId});
|
||||
sendToFlutter(ToFlutterAppEnum.showCommandJump.code, {
|
||||
"scheme": scheme,
|
||||
"activityId": activityId,
|
||||
});
|
||||
|
||||
//跳转至网页
|
||||
void taskToWebViewPage(
|
||||
{required String linkUrl, required String activityId}) =>
|
||||
sendToFlutter(ToFlutterAppEnum.showToWebViewPage.code,
|
||||
{"linkUrl": linkUrl, "activityId": activityId});
|
||||
void taskToWebViewPage({
|
||||
required String linkUrl,
|
||||
required String activityId,
|
||||
}) =>
|
||||
sendToFlutter(ToFlutterAppEnum.showToWebViewPage.code, {
|
||||
"linkUrl": linkUrl,
|
||||
"activityId": activityId,
|
||||
});
|
||||
|
||||
void checkStartBroadcaster() =>
|
||||
sendToFlutter(ToFlutterAppEnum.checkStartBroadcaster.code, {});
|
||||
|
||||
@@ -3,3 +3,4 @@ library;
|
||||
export 'package:web_tools/utils/app_bridge.dart';
|
||||
export 'package:web_tools/utils/config.dart';
|
||||
export 'package:web_tools/utils/model/model.dart';
|
||||
export 'package:web_tools/example_page.dart';
|
||||
|
||||
Reference in New Issue
Block a user