Browse Source

fixed camera disposing issues

pull/76/head
Khoren Markosyan 2 years ago
parent
commit
c25475420b
  1. 2
      example/lib/main.dart
  2. 71
      lib/src/ui/reader_widget.dart
  3. 1
      lib/src/ui/writer_widget.dart

2
example/lib/main.dart

@ -4,7 +4,7 @@ import 'package:flutter_zxing/flutter_zxing.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
void main() { void main() {
zx.setLogEnabled(kDebugMode); zx.setLogEnabled(!kDebugMode);
runApp(const MyApp()); runApp(const MyApp());
} }

71
lib/src/ui/reader_widget.dart

@ -5,10 +5,9 @@ import 'dart:math';
import 'package:camera/camera.dart'; import 'package:camera/camera.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
// import 'package:flutter_beep/flutter_beep.dart';
import '../../flutter_zxing.dart'; import '../../flutter_zxing.dart';
/// Widget to scan a code from the camera stream
class ReaderWidget extends StatefulWidget { class ReaderWidget extends StatefulWidget {
const ReaderWidget({ const ReaderWidget({
super.key, super.key,
@ -18,7 +17,7 @@ class ReaderWidget extends StatefulWidget {
this.codeFormat = Format.any, this.codeFormat = Format.any,
this.tryHarder = false, this.tryHarder = false,
this.tryInverted = false, this.tryInverted = false,
this.showCroppingRect = true, this.showScannerOverlay = true,
this.scannerOverlay, this.scannerOverlay,
this.showFlashlight = true, this.showFlashlight = true,
this.allowPinchZoom = true, this.allowPinchZoom = true,
@ -30,20 +29,49 @@ class ReaderWidget extends StatefulWidget {
const DecoratedBox(decoration: BoxDecoration(color: Colors.black)), const DecoratedBox(decoration: BoxDecoration(color: Colors.black)),
}); });
/// Called when a code is detected
final Function(Code) onScan; final Function(Code) onScan;
/// Called when a code is not detected
final Function()? onScanFailure; final Function()? onScanFailure;
/// Called when the camera controller is created
final Function(CameraController?)? onControllerCreated; final Function(CameraController?)? onControllerCreated;
/// Code format to scan
final int codeFormat; final int codeFormat;
/// Try harder to detect a code
final bool tryHarder; final bool tryHarder;
/// Try to detect inverted code
final bool tryInverted; final bool tryInverted;
final bool showCroppingRect;
/// Show cropping rect
final bool showScannerOverlay;
/// Custom scanner overlay
final ScannerOverlay? scannerOverlay; final ScannerOverlay? scannerOverlay;
/// Show flashlight button
final bool showFlashlight; final bool showFlashlight;
/// Allow pinch zoom
final bool allowPinchZoom; final bool allowPinchZoom;
/// Delay between scans when no code is detected
final Duration scanDelay; final Duration scanDelay;
/// Crop percent of the screen
final double cropPercent; final double cropPercent;
/// Camera resolution
final ResolutionPreset resolution; final ResolutionPreset resolution;
/// Delay between scans when a code is detected
final Duration scanDelaySuccess; final Duration scanDelaySuccess;
/// Loading widget while camera is initializing. Default is a black screen
final Widget loading; final Widget loading;
@override @override
@ -130,34 +158,37 @@ class _ReaderWidgetState extends State<ReaderWidget>
} }
Future<void> onNewCameraSelected(CameraDescription cameraDescription) async { Future<void> onNewCameraSelected(CameraDescription cameraDescription) async {
if (controller != null) { final CameraController? oldController = controller;
controller?.removeListener(rebuildOnMount); if (oldController != null) {
await controller!.dispose(); // controller?.removeListener(rebuildOnMount);
controller = null;
await oldController.dispose();
} }
controller = CameraController( final CameraController cameraController = CameraController(
cameraDescription, cameraDescription,
widget.resolution, widget.resolution,
enableAudio: false, enableAudio: false,
imageFormatGroup: imageFormatGroup:
isAndroid() ? ImageFormatGroup.yuv420 : ImageFormatGroup.bgra8888, isAndroid() ? ImageFormatGroup.yuv420 : ImageFormatGroup.bgra8888,
); );
if (controller == null) { controller = cameraController;
return; cameraController.addListener(rebuildOnMount);
}
try { try {
await controller!.initialize(); await cameraController.initialize();
await controller!.setFlashMode(FlashMode.off); await cameraController.setFlashMode(FlashMode.off);
_maxZoomLevel = await controller!.getMaxZoomLevel(); cameraController
_minZoomLevel = await controller!.getMinZoomLevel(); .getMaxZoomLevel()
controller!.startImageStream(processImageStream); .then((double value) => _maxZoomLevel = value);
cameraController
.getMinZoomLevel()
.then((double value) => _minZoomLevel = value);
cameraController.startImageStream(processImageStream);
} on CameraException catch (e) { } on CameraException catch (e) {
debugPrint('${e.code}: ${e.description}'); debugPrint('${e.code}: ${e.description}');
} catch (e) { } catch (e) {
debugPrint('Error: $e'); debugPrint('Error: $e');
} }
controller!.addListener(rebuildOnMount);
rebuildOnMount(); rebuildOnMount();
widget.onControllerCreated?.call(controller); widget.onControllerCreated?.call(controller);
} }
@ -167,7 +198,7 @@ class _ReaderWidgetState extends State<ReaderWidget>
_isProcessing = true; _isProcessing = true;
try { try {
final double cropPercent = final double cropPercent =
widget.showCroppingRect ? widget.cropPercent : 0; widget.showScannerOverlay ? widget.cropPercent : 0;
final int cropSize = final int cropSize =
(min(image.width, image.height) * cropPercent).round(); (min(image.width, image.height) * cropPercent).round();
final Params params = Params( final Params params = Params(
@ -230,7 +261,7 @@ class _ReaderWidgetState extends State<ReaderWidget>
), ),
), ),
), ),
if (widget.showCroppingRect) if (widget.showScannerOverlay)
Container( Container(
decoration: ShapeDecoration( decoration: ShapeDecoration(
shape: widget.scannerOverlay ?? shape: widget.scannerOverlay ??

1
lib/src/ui/writer_widget.dart

@ -5,6 +5,7 @@ import 'package:image/image.dart' as imglib;
import '../../flutter_zxing.dart'; import '../../flutter_zxing.dart';
/// Widget to create a code from a text and barcode format
class WriterWidget extends StatefulWidget { class WriterWidget extends StatefulWidget {
const WriterWidget({ const WriterWidget({
super.key, super.key,

Loading…
Cancel
Save