如何在Flutter Widget中监听JavaScript回调?
如何在Flutter Web中监听Paddle的eventCallback回调
方案一:通过window.postMessage实现通信
1. 修改index.html中的Paddle脚本
把原本的eventCallback改成将事件数据通过postMessage发送给Flutter:
<script type="text/javascript"> Paddle.Setup({ eventCallback: function (eventData) { console.log(eventData); // 发送事件数据到Flutter window.postMessage({ type: 'paddleEvent', data: eventData }, '*'); } }); </script>
2. 在Dart代码中监听事件
使用dart:html包监听window的message事件,解析并处理Paddle的回调数据:
import 'dart:html' as html; import 'package:flutter/material.dart'; class PaddleEventListenerWidget extends StatefulWidget { @override _PaddleEventListenerWidgetState createState() => _PaddleEventListenerWidgetState(); } class _PaddleEventListenerWidgetState extends State<PaddleEventListenerWidget> { dynamic _latestPaddleEvent; @override void initState() { super.initState(); // 注册message事件监听 html.window.addEventListener('message', _handlePaddleEvent); } void _handlePaddleEvent(html.Event event) { final messageEvent = event as html.MessageEvent; final eventData = messageEvent.data; // 过滤出Paddle的事件 if (eventData is Map && eventData['type'] == 'paddleEvent') { setState(() { _latestPaddleEvent = eventData['data']; }); // 在这里添加你的业务逻辑处理 print('收到Paddle事件: $_latestPaddleEvent'); } } @override void dispose() { // 移除监听,避免内存泄漏 html.window.removeEventListener('message', _handlePaddleEvent); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( body: Center( child: Text(_latestPaddleEvent != null ? '最新事件: ${_latestPaddleEvent.toString()}' : '等待Paddle事件'), ), ); } }
方案二:使用package:js直接绑定JS函数
1. 添加依赖
在pubspec.yaml中引入js包:
dependencies: flutter: sdk: flutter js: ^0.6.7
2. 修改index.html中的脚本
定义一个全局JS函数,让Paddle的eventCallback直接调用它:
<script type="text/javascript"> // 全局函数,用于接收Paddle事件 window.handlePaddleEvent = function(eventData) { console.log(eventData); }; Paddle.Setup({ eventCallback: function (eventData) { window.handlePaddleEvent(eventData); } }); </script>
3. 在Dart代码中绑定回调
通过package:js将Dart函数绑定到全局JS函数,直接接收事件:
import 'package:flutter/material.dart'; import 'package:js/js.dart'; // 声明全局JS函数 @JS() external set handlePaddleEvent(void Function(dynamic eventData) callback); class PaddleEventWidget extends StatefulWidget { @override _PaddleEventWidgetState createState() => _PaddleEventWidgetState(); } class _PaddleEventWidgetState extends State<PaddleEventWidget> { dynamic _eventData; @override void initState() { super.initState(); // 将Dart函数绑定到全局JS函数 handlePaddleEvent = allowInterop(_onPaddleEvent); } void _onPaddleEvent(dynamic eventData) { setState(() { _eventData = eventData; }); // 处理事件逻辑 print('Paddle事件数据: $_eventData'); } @override void dispose() { // 清空回调,防止内存泄漏 handlePaddleEvent = allowInterop((_) {}); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( body: Padding( padding: EdgeInsets.all(16), child: Text(_eventData != null ? '事件详情: ${_eventData.toString()}' : '未收到事件'), ), ); } }
两种方案对比:
- 方案一无需额外依赖,适合快速实现,兼容性好;
- 方案二代码更简洁直接,逻辑更清晰,适合复杂场景。
内容的提问来源于stack exchange,提问作者Jonas
相关产品推荐
相关产品推荐

