前些日子写了一个flutter_barcode_sdk,配合已经存在的Flutter camera插件可以实现摄像头扫码 - 从Java层获取摄像头数据,通过Dart传递,再到Java去做解码。这个过程可以优化。这篇文章的目的是把摄像头控制和二维码扫描合并到Android代码里,然后封装出一整个Flutter插件。
基于Android TextView的Flutter自定义Widget
根据官方文档,我们先做一个最简单的自定义widget。
-
创建插件工程:
flutter create --org com.dynamsoft --template=plugin --platforms=android -a java flutter_qrcode_scanner
-
打开
lib/flutter_qrcode_scanner.dart
文件,把自动生成的代码替换成:class ScannerView extends StatefulWidget { const ScannerView({Key? key}) : super(key: key); @override State<StatefulWidget> createState() => _ScannerViewState(); } class _ScannerViewState extends State<ScannerView> { @override void initState() { super.initState(); } @override Widget build(BuildContext context) { const String viewType = 'com.dynamsoft.flutter_qrcode_scanner/nativeview'; final Map<String, dynamic> creationParams = <String, dynamic>{}; return AndroidView( viewType: viewType, creationParams: creationParams, creationParamsCodec: const StandardMessageCodec(), ); } }
-
在Android目录下创建一个
NativeView.java
文件。创建一个TextView
,并在getView()
中返回:import android.content.Context; import android.graphics.Color; import android.view.View; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import io.flutter.plugin.platform.PlatformView; import java.util.Map; class NativeView implements PlatformView { @NonNull private final TextView textView; NativeView(@NonNull Context context, int id, @Nullable Map<String, Object> creationParams) { textView = new TextView(context); textView.setTextSize(72); textView.setBackgroundColor(Color.rgb(255, 255, 255)); textView.setText("Rendered on a native Android view (id: " + id + ")"); } @NonNull @Override public View getView() { return textView; } @Override public void dispose() { } }
接下来创建
NativeViewFactory.java
,用于初始化NativeView
:import android.content.Context; import android.view.View; import androidx.annotation.Nullable; import androidx.annotation.NonNull; import io.flutter.plugin.common.BinaryMessenger; import io.flutter.plugin.common.StandardMessageCodec; import io.flutter.plugin.platform.PlatformView; import io.flutter.plugin.platform.PlatformViewFactory; import java.util.Map; class NativeViewFactory extends PlatformViewFactory { @NonNull private final BinaryMessenger messenger; NativeViewFactory(@NonNull BinaryMessenger messenger) { super(StandardMessageCodec.INSTANCE); this.messenger = messenger; } @NonNull @Override public PlatformView create(@NonNull Context context, int id, @Nullable Object args) { final Map<String, Object> creationParams = (Map<String, Object>) args; return new NativeView(context, id, creationParams); } }
在自动生成的
FlutterQrcodeScannerPlugin.java
中,注册NativeViewFactory
:@Override public void onAttachedToEngine