Navaron Bracke

fix the barcode scanner controller example

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:mobile_scanner/mobile_scanner.dart';
import 'package:mobile_scanner_example/scanner_button_widgets.dart';
import 'package:mobile_scanner_example/scanner_error_widget.dart';
class BarcodeScannerWithController extends StatefulWidget {
... ... @@ -25,29 +27,23 @@ class _BarcodeScannerWithControllerState
// returnImage: false,
);
bool isStarted = true;
StreamSubscription<Object?>? _barcodesSubscription;
void _startOrStop() {
try {
if (isStarted) {
controller.stop();
} else {
controller.start();
@override
void initState() {
super.initState();
_barcodesSubscription = controller.barcodes.listen((event) {
if (!context.mounted) {
return;
}
setState(() {
isStarted = !isStarted;
barcode = event;
});
} on Exception catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Something went wrong! $e'),
backgroundColor: Colors.red,
),
);
}
}
});
int? numberOfCameras;
controller.start();
}
@override
Widget build(BuildContext context) {
... ... @@ -59,22 +55,11 @@ class _BarcodeScannerWithControllerState
return Stack(
children: [
MobileScanner(
onScannerStarted: (arguments) {
if (mounted && arguments?.numberOfCameras != null) {
numberOfCameras = arguments!.numberOfCameras;
setState(() {});
}
},
controller: controller,
errorBuilder: (context, error, child) {
return ScannerErrorWidget(error: error);
},
fit: BoxFit.contain,
onDetect: (barcode) {
setState(() {
this.barcode = barcode;
});
},
),
Align(
alignment: Alignment.bottomCenter,
... ... @@ -85,44 +70,8 @@ class _BarcodeScannerWithControllerState
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ValueListenableBuilder(
valueListenable: controller.hasTorchState,
builder: (context, state, child) {
if (state != true) {
return const SizedBox.shrink();
}
return IconButton(
color: Colors.white,
icon: ValueListenableBuilder<TorchState>(
valueListenable: controller.torchState,
builder: (context, state, child) {
switch (state) {
case TorchState.off:
return const Icon(
Icons.flash_off,
color: Colors.grey,
);
case TorchState.on:
return const Icon(
Icons.flash_on,
color: Colors.yellow,
);
}
},
),
iconSize: 32.0,
onPressed: () => controller.toggleTorch(),
);
},
),
IconButton(
color: Colors.white,
icon: isStarted
? const Icon(Icons.stop)
: const Icon(Icons.play_arrow),
iconSize: 32.0,
onPressed: _startOrStop,
),
ToggleFlashlightButton(controller: controller),
StartStopMobileScannerButton(controller: controller),
Center(
child: SizedBox(
width: MediaQuery.of(context).size.width - 200,
... ... @@ -140,55 +89,8 @@ class _BarcodeScannerWithControllerState
),
),
),
IconButton(
color: Colors.white,
icon: ValueListenableBuilder<CameraFacing>(
valueListenable: controller.cameraFacingState,
builder: (context, state, child) {
switch (state) {
case CameraFacing.front:
return const Icon(Icons.camera_front);
case CameraFacing.back:
return const Icon(Icons.camera_rear);
}
},
),
iconSize: 32.0,
onPressed: (numberOfCameras ?? 0) < 2
? null
: () => controller.switchCamera(),
),
IconButton(
color: Colors.white,
icon: const Icon(Icons.image),
iconSize: 32.0,
onPressed: () async {
final ImagePicker picker = ImagePicker();
// Pick an image
final XFile? image = await picker.pickImage(
source: ImageSource.gallery,
);
if (image != null) {
if (await controller.analyzeImage(image.path)) {
if (!context.mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Barcode found!'),
backgroundColor: Colors.green,
),
);
} else {
if (!context.mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('No barcode found!'),
backgroundColor: Colors.red,
),
);
}
}
},
),
SwitchCameraButton(controller: controller),
AnalyzeImageFromGalleryButton(controller: controller),
],
),
),
... ... @@ -199,4 +101,11 @@ class _BarcodeScannerWithControllerState
),
);
}
@override
Future<void> dispose() async {
_barcodesSubscription?.cancel();
await controller.dispose();
super.dispose();
}
}
... ...