Bladeren bron

Added possibility to choose facing camera on start.

Moved the size listener to plugin side.
flutter-beta
Julian Steenbakker 5 jaren geleden
bovenliggende
commit
e6b74ac752
Geen bekende sleutel gevonden voor deze handtekening in de database GPG sleutel-ID: 16E437C7A3D94250
8 gewijzigde bestanden met toevoegingen van 211 en 143 verwijderingen
  1. +17
    -6
      android/src/main/kotlin/net/touchcapture/qr/flutterqr/QRView.kt
  2. +3
    -2
      android/src/main/kotlin/net/touchcapture/qr/flutterqr/QRViewFactory.kt
  3. +1
    -0
      example/.gitignore
  4. +0
    -2
      example/ios/Runner.xcodeproj/project.pbxproj
  5. +12
    -19
      example/lib/main.dart
  6. +69
    -50
      ios/Classes/QRView.swift
  7. +2
    -2
      ios/Classes/QRViewFactory.swift
  8. +107
    -62
      lib/src/qr_code_scanner.dart

+ 17
- 6
android/src/main/kotlin/net/touchcapture/qr/flutterqr/QRView.kt Bestand weergeven

@@ -17,7 +17,7 @@ import io.flutter.plugin.common.BinaryMessenger
import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.platform.PlatformView import io.flutter.plugin.platform.PlatformView
class QRView(messenger: BinaryMessenger, id: Int, private val context: Context) :
class QRView(messenger: BinaryMessenger, id: Int, private val context: Context, private val params: HashMap<String, Any>) :
PlatformView, MethodChannel.MethodCallHandler { PlatformView, MethodChannel.MethodCallHandler {


private var isTorchOn: Boolean = false private var isTorchOn: Boolean = false
@@ -66,6 +66,12 @@ class QRView(messenger: BinaryMessenger, id: Int, private val context: Context)


override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
when(call.method){ when(call.method){
"startScan" -> {
startScan()
}
"stopScan" -> {
stopScan()
}
"flipCamera" -> { "flipCamera" -> {
flipCamera() flipCamera()
} }
@@ -127,14 +133,16 @@ class QRView(messenger: BinaryMessenger, id: Int, private val context: Context)


private fun initBarCodeView(): BarcodeView? { private fun initBarCodeView(): BarcodeView? {
if (barcodeView == null) { if (barcodeView == null) {
barcodeView = createBarCodeView()
barcodeView = BarcodeView(Shared.activity)
if (params["cameraFacing"] as Int == 1) {
barcodeView?.cameraSettings?.requestedCameraId = CameraInfo.CAMERA_FACING_FRONT
}
} }
return barcodeView return barcodeView
} }


private fun createBarCodeView(): BarcodeView {
val barcode = BarcodeView(Shared.activity)
barcode.decodeContinuous(
private fun startScan() {
barcodeView?.decodeContinuous(
object : BarcodeCallback { object : BarcodeCallback {
override fun barcodeResult(result: BarcodeResult) { override fun barcodeResult(result: BarcodeResult) {
val code = mapOf( val code = mapOf(
@@ -147,7 +155,10 @@ class QRView(messenger: BinaryMessenger, id: Int, private val context: Context)
override fun possibleResultPoints(resultPoints: List<ResultPoint>) {} override fun possibleResultPoints(resultPoints: List<ResultPoint>) {}
} }
) )
return barcode
}

private fun stopScan() {
barcodeView?.stopDecoding()
} }


private fun hasCameraPermission(): Boolean { private fun hasCameraPermission(): Boolean {


+ 3
- 2
android/src/main/kotlin/net/touchcapture/qr/flutterqr/QRViewFactory.kt Bestand weergeven

@@ -10,8 +10,9 @@ import io.flutter.plugin.platform.PlatformViewFactory
class QRViewFactory(private val messenger: BinaryMessenger) : class QRViewFactory(private val messenger: BinaryMessenger) :
PlatformViewFactory(StandardMessageCodec.INSTANCE) { PlatformViewFactory(StandardMessageCodec.INSTANCE) {


override fun create(context: Context, id: Int, obj: Any?): PlatformView {
return QRView(messenger, id, context)
override fun create(context: Context, id: Int, args: Any?): PlatformView {
val params = args as HashMap<String, Any>
return QRView(messenger, id, context, params)
} }


} }

+ 1
- 0
example/.gitignore Bestand weergeven

@@ -9,6 +9,7 @@
.buildlog/ .buildlog/
.history .history
.svn/ .svn/
.last_build_id


# IntelliJ related # IntelliJ related
*.iml *.iml


+ 0
- 2
example/ios/Runner.xcodeproj/project.pbxproj Bestand weergeven

@@ -264,13 +264,11 @@
); );
inputPaths = ( inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
"${PODS_ROOT}/../Flutter/Flutter.framework",
"${BUILT_PRODUCTS_DIR}/MTBBarcodeScanner/MTBBarcodeScanner.framework", "${BUILT_PRODUCTS_DIR}/MTBBarcodeScanner/MTBBarcodeScanner.framework",
"${BUILT_PRODUCTS_DIR}/qr_code_scanner/qr_code_scanner.framework", "${BUILT_PRODUCTS_DIR}/qr_code_scanner/qr_code_scanner.framework",
); );
name = "[CP] Embed Pods Frameworks"; name = "[CP] Embed Pods Frameworks";
outputPaths = ( outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MTBBarcodeScanner.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MTBBarcodeScanner.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/qr_code_scanner.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/qr_code_scanner.framework",
); );


+ 12
- 19
example/lib/main.dart Bestand weergeven

@@ -154,25 +154,18 @@ class _QRViewExampleState extends State<QRViewExample> {
: 300.0; : 300.0;
// To ensure the Scanner view is properly sizes after rotation // To ensure the Scanner view is properly sizes after rotation
// we need to listen for Flutter SizeChanged notification and update controller // we need to listen for Flutter SizeChanged notification and update controller
return NotificationListener<SizeChangedLayoutNotification>(
onNotification: (notification) {
Future.microtask(
() => controller?.updateDimensions(qrKey, scanArea: scanArea));
return false;
},
child: SizeChangedLayoutNotifier(
key: const Key('qr-size-notifier'),
child: QRView(
key: qrKey,
onQRViewCreated: _onQRViewCreated,
overlay: QrScannerOverlayShape(
borderColor: Colors.red,
borderRadius: 10,
borderLength: 30,
borderWidth: 10,
cutOutSize: scanArea,
),
)));
return QRView(
key: qrKey,
cameraFacing: CameraFacing.front,
onQRViewCreated: _onQRViewCreated,
overlay: QrScannerOverlayShape(
borderColor: Colors.red,
borderRadius: 10,
borderLength: 30,
borderWidth: 10,
cutOutSize: scanArea,
),
);
} }


void _onQRViewCreated(QRViewController controller) { void _onQRViewCreated(QRViewController controller) {


+ 69
- 50
ios/Classes/QRView.swift Bestand weergeven

@@ -13,67 +13,28 @@ public class QRView:NSObject,FlutterPlatformView {
var scanner: MTBBarcodeScanner? var scanner: MTBBarcodeScanner?
var registrar: FlutterPluginRegistrar var registrar: FlutterPluginRegistrar
var channel: FlutterMethodChannel var channel: FlutterMethodChannel
var cameraFacing: MTBCamera
public init(withFrame frame: CGRect, withRegistrar registrar: FlutterPluginRegistrar, withId id: Int64){
public init(withFrame frame: CGRect, withRegistrar registrar: FlutterPluginRegistrar, withId id: Int64, params: Dictionary<String, Any>){
self.registrar = registrar self.registrar = registrar
previewView = UIView(frame: frame) previewView = UIView(frame: frame)
cameraFacing = MTBCamera.init(rawValue: UInt(Int(params["cameraFacing"] as! Double))) ?? MTBCamera.back
channel = FlutterMethodChannel(name: "net.touchcapture.qr.flutterqr/qrview_\(id)", binaryMessenger: registrar.messenger()) channel = FlutterMethodChannel(name: "net.touchcapture.qr.flutterqr/qrview_\(id)", binaryMessenger: registrar.messenger())
} }
func isCameraAvailable(success: Bool) -> Void {
if success {
do {
try scanner?.startScanning(resultBlock: { [weak self] codes in
if let codes = codes {
for code in codes {
var typeString: String;
switch(code.type) {
case AVMetadataObject.ObjectType.aztec:
typeString = "AZTEC"
case AVMetadataObject.ObjectType.code39:
typeString = "CODE_39"
case AVMetadataObject.ObjectType.code93:
typeString = "CODE_93"
case AVMetadataObject.ObjectType.code128:
typeString = "CODE_128"
case AVMetadataObject.ObjectType.dataMatrix:
typeString = "DATA_MATRIX"
case AVMetadataObject.ObjectType.ean8:
typeString = "EAN_8"
case AVMetadataObject.ObjectType.ean13:
typeString = "EAN_13"
case AVMetadataObject.ObjectType.itf14:
typeString = "ITF"
case AVMetadataObject.ObjectType.pdf417:
typeString = "PDF_417"
case AVMetadataObject.ObjectType.qr:
typeString = "QR_CODE"
case AVMetadataObject.ObjectType.upce:
typeString = "UPC_E"
default:
return
}
guard let stringValue = code.stringValue else { continue }
let result = ["code": stringValue, "type": typeString]
self?.channel.invokeMethod("onRecognizeQR", arguments: result)
}
}
})
} catch {
NSLog("Unable to start scanning")
}
} else {
UIAlertView(title: "Scanning Unavailable", message: "This app does not have permission to access the camera", delegate: nil, cancelButtonTitle: nil, otherButtonTitles: "Ok").show()
}
deinit {
scanner?.stopScanning()
} }
public func view() -> UIView { public func view() -> UIView {
channel.setMethodCallHandler({ channel.setMethodCallHandler({
[weak self] (call: FlutterMethodCall, result: FlutterResult) -> Void in
[weak self] (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
switch(call.method){ switch(call.method){
case "setDimensions": case "setDimensions":
let arguments = call.arguments as! Dictionary<String, Double> let arguments = call.arguments as! Dictionary<String, Double>
self?.setDimensions(width: arguments["width"] ?? 0, height: arguments["height"] ?? 0, scanArea: arguments["scanArea"] ?? 0) self?.setDimensions(width: arguments["width"] ?? 0, height: arguments["height"] ?? 0, scanArea: arguments["scanArea"] ?? 0)
case "startScan":
self?.startScan(result)
case "flipCamera": case "flipCamera":
self?.flipCamera() self?.flipCamera()
case "toggleFlash": case "toggleFlash":
@@ -106,9 +67,67 @@ public class QRView:NSObject,FlutterPlatformView {
self.scanner?.scanRect = CGRect(x: Double(midX) - (scanArea / 2), y: Double(midY) - (scanArea / 2), width: scanArea, height: scanArea) self.scanner?.scanRect = CGRect(x: Double(midX) - (scanArea / 2), y: Double(midY) - (scanArea / 2), width: scanArea, height: scanArea)
} }
} }


MTBBarcodeScanner.requestCameraPermission(success: isCameraAvailable)
}
}
func startScan(_ result: @escaping FlutterResult) -> Void {
scanner = MTBBarcodeScanner(previewView: previewView)
MTBBarcodeScanner.requestCameraPermission(success: { permissionGranted in
if permissionGranted {
do {
try self.scanner?.startScanning(with: self.cameraFacing, resultBlock: { [weak self] codes in
if let codes = codes {
for code in codes {
var typeString: String;
switch(code.type) {
case AVMetadataObject.ObjectType.aztec:
typeString = "AZTEC"
case AVMetadataObject.ObjectType.code39:
typeString = "CODE_39"
case AVMetadataObject.ObjectType.code93:
typeString = "CODE_93"
case AVMetadataObject.ObjectType.code128:
typeString = "CODE_128"
case AVMetadataObject.ObjectType.dataMatrix:
typeString = "DATA_MATRIX"
case AVMetadataObject.ObjectType.ean8:
typeString = "EAN_8"
case AVMetadataObject.ObjectType.ean13:
typeString = "EAN_13"
case AVMetadataObject.ObjectType.itf14:
typeString = "ITF"
case AVMetadataObject.ObjectType.pdf417:
typeString = "PDF_417"
case AVMetadataObject.ObjectType.qr:
typeString = "QR_CODE"
case AVMetadataObject.ObjectType.upce:
typeString = "UPC_E"
default:
return
}
guard let stringValue = code.stringValue else { continue }
let result = ["code": stringValue, "type": typeString]
self?.channel.invokeMethod("onRecognizeQR", arguments: result)
}
}
})
} catch {
let error = FlutterError(code: "unknown-error", message: "Unable to start scanning", details: nil)
result(error)
}
} else {
let error = FlutterError(code: "cameraPermission", message: "Permission denied to access the camera", details: nil)
result(error)
}
})
}
func stopScan(){
if let sc: MTBBarcodeScanner = scanner {
if sc.isScanning() {
sc.stopScanning()
}
} }
} }


+ 2
- 2
ios/Classes/QRViewFactory.swift Bestand weergeven

@@ -17,8 +17,8 @@ public class QRViewFactory: NSObject, FlutterPlatformViewFactory {
} }
public func create(withFrame frame: CGRect, viewIdentifier viewId: Int64, arguments args: Any?) -> FlutterPlatformView { public func create(withFrame frame: CGRect, viewIdentifier viewId: Int64, arguments args: Any?) -> FlutterPlatformView {
let dictionary = args as! Dictionary<String, Double>
return QRView(withFrame: CGRect(x: 0, y: 0, width: dictionary["width"] ?? 0, height: dictionary["height"] ?? 0), withRegistrar: registrar!,withId: viewId)
let params = args as! Dictionary<String, Double>
return QRView(withFrame: frame, withRegistrar: registrar!,withId: viewId, params: params)
} }
public func createArgsCodec() -> FlutterMessageCodec & NSObjectProtocol { public func createArgsCodec() -> FlutterMessageCodec & NSObjectProtocol {


+ 107
- 62
lib/src/qr_code_scanner.dart Bestand weergeven

@@ -7,6 +7,14 @@ import 'package:qr_code_scanner/qr_code_scanner.dart';


typedef QRViewCreatedCallback = void Function(QRViewController); typedef QRViewCreatedCallback = void Function(QRViewController);


enum CameraFacing {
/// Shows back facing camera.
back,

/// Shows front facing camera.
front
}

enum BarcodeFormat { enum BarcodeFormat {
/// Aztec 2D barcode format. /// Aztec 2D barcode format.
aztec, aztec,
@@ -80,6 +88,11 @@ const _formatNames = <String, BarcodeFormat>{
'UPC_EAN_EXTENSION': BarcodeFormat.upcEanExtension, 'UPC_EAN_EXTENSION': BarcodeFormat.upcEanExtension,
}; };


/// The [Barcode] object holds information about the barcode or qr code.
///
/// [code] is the content of the barcode.
/// [format] displays which type the code is.
/// Only for Android, [rawBytes] gives a list of bytes of the result.
class Barcode { class Barcode {
Barcode(this.code, this.format, this.rawBytes); Barcode(this.code, this.format, this.rawBytes);


@@ -90,60 +103,84 @@ class Barcode {
final List<int> rawBytes; final List<int> rawBytes;
} }


/// The [QRView] is the view where the camera and the barcode scanner gets displayed.
class QRView extends StatefulWidget { class QRView extends StatefulWidget {
const QRView({ const QRView({
@required Key key, @required Key key,
@required this.onQRViewCreated, @required this.onQRViewCreated,
this.overlay, this.overlay,
this.overlayMargin = EdgeInsets.zero, this.overlayMargin = EdgeInsets.zero,
this.cameraFacing = CameraFacing.back,
}) : assert(key != null), }) : assert(key != null),
assert(onQRViewCreated != null), assert(onQRViewCreated != null),
super(key: key); super(key: key);


final QRViewCreatedCallback onQRViewCreated; final QRViewCreatedCallback onQRViewCreated;

final ShapeBorder overlay; final ShapeBorder overlay;
final EdgeInsetsGeometry overlayMargin; final EdgeInsetsGeometry overlayMargin;
final CameraFacing cameraFacing;


@override @override
State<StatefulWidget> createState() => _QRViewState(); State<StatefulWidget> createState() => _QRViewState();
} }


class _QRViewState extends State<QRView> { class _QRViewState extends State<QRView> {

var _channel;

@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return NotificationListener(
onNotification: onNotification,
child: SizeChangedLayoutNotifier(
child: (widget.overlay != null) ?
_getPlatformQrViewWithOverlay() :
_getPlatformQrView(),
),
);
}

bool onNotification(notification) {
Future.microtask(() => {
QRViewController.updateDimensions(
widget.key,
_channel,
scanArea: widget.overlay != null ?
(widget.overlay as QrScannerOverlayShape).cutOutSize : 0.0)
});
return false;
}

Widget _getPlatformQrViewWithOverlay() {
return Stack( return Stack(
children: [ children: [
_getPlatformQrView(widget.key),
if (widget.overlay != null)
Container(
padding: widget.overlayMargin,
decoration: ShapeDecoration(
shape: widget.overlay,
),
)
else
Container(),
_getPlatformQrView(),
Container(
padding: widget.overlayMargin,
decoration: ShapeDecoration(
shape: widget.overlay,
),
)
], ],
); );
} }


Widget _getPlatformQrView(GlobalKey key) {
Widget _getPlatformQrView() {
Widget _platformQrView; Widget _platformQrView;
switch (defaultTargetPlatform) { switch (defaultTargetPlatform) {
case TargetPlatform.android: case TargetPlatform.android:
_platformQrView = AndroidView( _platformQrView = AndroidView(
viewType: 'net.touchcapture.qr.flutterqr/qrview', viewType: 'net.touchcapture.qr.flutterqr/qrview',
onPlatformViewCreated: _onPlatformViewCreated, onPlatformViewCreated: _onPlatformViewCreated,
creationParams: _QrCameraSettings(cameraFacing: widget.cameraFacing).toMap(),
creationParamsCodec: StandardMessageCodec(),
); );
break; break;
case TargetPlatform.iOS: case TargetPlatform.iOS:
_platformQrView = UiKitView( _platformQrView = UiKitView(
viewType: 'net.touchcapture.qr.flutterqr/qrview', viewType: 'net.touchcapture.qr.flutterqr/qrview',
onPlatformViewCreated: _onPlatformViewCreated, onPlatformViewCreated: _onPlatformViewCreated,
creationParams:
_CreationParams.fromWidget(MediaQuery.of(context).size.width, 400)
.toMap(),
creationParams: _QrCameraSettings(cameraFacing: widget.cameraFacing).toMap(),
creationParamsCodec: StandardMessageCodec(), creationParamsCodec: StandardMessageCodec(),
); );
break; break;
@@ -155,101 +192,109 @@ class _QRViewState extends State<QRView> {
} }


void _onPlatformViewCreated(int id) { void _onPlatformViewCreated(int id) {
if (widget.onQRViewCreated == null) {
return;
}

// We pass the cutout size so that the scanner respects the scan area. // We pass the cutout size so that the scanner respects the scan area.
var cutOutSize = 0.0; var cutOutSize = 0.0;
if (widget.overlay != null) { if (widget.overlay != null) {
cutOutSize = (widget.overlay as QrScannerOverlayShape).cutOutSize; cutOutSize = (widget.overlay as QrScannerOverlayShape).cutOutSize;
} }


widget.onQRViewCreated(QRViewController._(id, widget.key, cutOutSize));
}
}
_channel = MethodChannel('net.touchcapture.qr.flutterqr/qrview_$id');


class _CreationParams {
_CreationParams({this.width, this.height});
// Start scan after creation of the view
final controller = QRViewController._(_channel, widget.key, cutOutSize)
.._startScan(widget.key, cutOutSize);


static _CreationParams fromWidget(double width, double height) {
return _CreationParams(
width: width,
height: height,
);
// Initialize the controller for controlling the QRView
if (widget.onQRViewCreated != null) {
widget.onQRViewCreated(controller);
}
} }
}

class _QrCameraSettings {
_QrCameraSettings({
this.cameraFacing,
});


final double width;
final double height;
final CameraFacing cameraFacing;


Map<String, dynamic> toMap() { Map<String, dynamic> toMap() {
return <String, dynamic>{ return <String, dynamic>{
'width': width,
'height': height,
'cameraFacing': cameraFacing.index,
}; };
} }

} }


class QRViewController { class QRViewController {
QRViewController._(int id, GlobalKey qrKey, double scanArea)
: _channel = MethodChannel('net.touchcapture.qr.flutterqr/qrview_$id') {
updateDimensions(qrKey, scanArea: scanArea);
_channel.setMethodCallHandler(
(call) async {
switch (call.method) {
case scanMethodCall:
if (call.arguments != null) {
final args = call.arguments as Map;
final code = args['code'] as String;
final rawType = args['type'] as String;
// Raw bytes are only supported by Android.
final rawBytes = args['rawBytes'] as List<int>;
final format = _formatNames[rawType];
if (format != null) {
final barcode = Barcode(code, format, rawBytes);
_scanUpdateController.sink.add(barcode);
} else {
throw Exception('Unexpected barcode type $rawType');
}
}
}
},
);
QRViewController._(MethodChannel channel, GlobalKey qrKey, double scanArea)
: _channel = channel {
_channel.setMethodCallHandler(_onMethodCall);
} }


static const scanMethodCall = 'onRecognizeQR';

final MethodChannel _channel; final MethodChannel _channel;

final StreamController<Barcode> _scanUpdateController = final StreamController<Barcode> _scanUpdateController =
StreamController<Barcode>(); StreamController<Barcode>();


Stream<Barcode> get scannedDataStream => _scanUpdateController.stream; Stream<Barcode> get scannedDataStream => _scanUpdateController.stream;


Future<void> _onMethodCall(MethodCall call) async {
switch (call.method) {
case 'onRecognizeQR':
if (call.arguments != null) {
final args = call.arguments as Map;
final code = args['code'] as String;
final rawType = args['type'] as String;
// Raw bytes are only supported by Android.
final rawBytes = args['rawBytes'] as List<int>;
final format = _formatNames[rawType];
if (format != null) {
final barcode = Barcode(code, format, rawBytes);
_scanUpdateController.sink.add(barcode);
} else {
throw Exception('Unexpected barcode type $rawType');
}
}
}
}

/// Starts the barcode scanner
Future<void> _startScan(GlobalKey key, double cutOutSize, ) async {
// We need to update the dimension before the scan is started.
QRViewController.updateDimensions(key, _channel, scanArea: cutOutSize);
return _channel.invokeMethod('startScan');
}

/// Flips the camera between available modes
void flipCamera() { void flipCamera() {
_channel.invokeMethod('flipCamera'); _channel.invokeMethod('flipCamera');
} }


/// Toggles the flashlight between available modes
void toggleFlash() { void toggleFlash() {
_channel.invokeMethod('toggleFlash'); _channel.invokeMethod('toggleFlash');
} }


/// Pauses barcode scanning
void pauseCamera() { void pauseCamera() {
_channel.invokeMethod('pauseCamera'); _channel.invokeMethod('pauseCamera');
} }


/// Resumes barcode scanning
void resumeCamera() { void resumeCamera() {
_channel.invokeMethod('resumeCamera'); _channel.invokeMethod('resumeCamera');
} }


/// Disposes the barcode stream.
void dispose() { void dispose() {
_scanUpdateController.close(); _scanUpdateController.close();
} }


void updateDimensions(GlobalKey key, {double scanArea}) {
/// Updates the view dimensions for iOS.
static void updateDimensions(GlobalKey key, MethodChannel channel, {double scanArea}) {
if (defaultTargetPlatform == TargetPlatform.iOS) { if (defaultTargetPlatform == TargetPlatform.iOS) {
final RenderBox renderBox = key.currentContext.findRenderObject(); final RenderBox renderBox = key.currentContext.findRenderObject();
_channel.invokeMethod('setDimensions', {
channel.invokeMethod('setDimensions', {
'width': renderBox.size.width, 'width': renderBox.size.width,
'height': renderBox.size.height, 'height': renderBox.size.height,
'scanArea': scanArea ?? 0 'scanArea': scanArea ?? 0


Laden…
Annuleren
Opslaan