之前分享了如何在Flutter插件中支持Android和Windows,这篇文章将增加Web插件的实现方法,以及创建一个简单的web一维码,二维码识别应用。
参考资源
- https://dart.dev/web/js-interop
- https://github.com/grandnexus/firebase-dart
- https://pub.dev/packages/js
开发Flutter Web插件
Web插件开发,主要问题是如何实现Dart和JavaScript的相互调用。官网提供的firebase_web
示例值得学习和参考。
初始化web插件
在当前的插件工程中增加Web模板:
flutter create --template=plugin --platforms=web .
和Windows, Android不同,web模板没有生成一个叫web
的目录,也没有生成任何的JavaScritp
代码文件。我们只看到一个新的flutter_barcode_sdk_web.dart
文件。
接下来把插件声明添加到pubspec.yaml
中:
flutter:
plugin:
platforms:
android:
package: com.dynamsoft.flutter_barcode_sdk
pluginClass: FlutterBarcodeSdkPlugin
windows:
pluginClass: FlutterBarcodeSdkPlugin
web:
pluginClass: FlutterBarcodeSdkWeb
fileName: flutter_barcode_sdk_web.dart
如何实现JavaScript和Dart交互
和其它平台一样,handleMethodCall()
是入口:
Future<dynamic> handleMethodCall(MethodCall call) async {
switch (call.method) {
case 'getPlatformVersion':
return getPlatformVersion();
default:
throw PlatformException(
code: 'Unimplemented',
details:
'flutter_barcode_sdk for web doesn\'t implement \'${call.method}\'',
);
}
}
但不同的是,web并不需要在插件中引入依赖库编译,我们要做的只是定义接口。
我定义了两个接口:decodeFile()
和decodeVideo()
,分别用于通过图像和通过视频来识别一维码和二维码。
BarcodeManager _barcodeManager = BarcodeManager();
/// Decode barcodes from an image file.
Future<List<Map<dynamic, dynamic>>> decodeFile(String file) async {
return _barcodeManager.decodeFile(file);
}
/// Decode barcodes from real-time video stream.
Future<void> decodeVideo() async {
_barcodeManager.decodeVideo();
}
在视频模式下,结果是通过回调返回的。然而,在上层的flutter_barcode_sdk.dart
中,回调函数引用没有办法通过invokeMethod
传递下来。我的解决方法是使用全局变量保存回调函数:
Future<void> decodeVideo(Function callback) async {
globalCallback = callback;
await _channel.invokeMethod('decodeVideo');
}
为了避免和其它平