Navaron Bracke

fix the return image sample

@@ -2,6 +2,7 @@ import 'dart:math'; @@ -2,6 +2,7 @@ import 'dart:math';
2 2
3 import 'package:flutter/material.dart'; 3 import 'package:flutter/material.dart';
4 import 'package:mobile_scanner/mobile_scanner.dart'; 4 import 'package:mobile_scanner/mobile_scanner.dart';
  5 +import 'package:mobile_scanner_example/scanner_button_widgets.dart';
5 import 'package:mobile_scanner_example/scanner_error_widget.dart'; 6 import 'package:mobile_scanner_example/scanner_error_widget.dart';
6 7
7 class BarcodeScannerReturningImage extends StatefulWidget { 8 class BarcodeScannerReturningImage extends StatefulWidget {
@@ -13,11 +14,7 @@ class BarcodeScannerReturningImage extends StatefulWidget { @@ -13,11 +14,7 @@ class BarcodeScannerReturningImage extends StatefulWidget {
13 } 14 }
14 15
15 class _BarcodeScannerReturningImageState 16 class _BarcodeScannerReturningImageState
16 - extends State<BarcodeScannerReturningImage>  
17 - with SingleTickerProviderStateMixin {  
18 - BarcodeCapture? barcode;  
19 - // MobileScannerArguments? arguments;  
20 - 17 + extends State<BarcodeScannerReturningImage> {
21 final MobileScannerController controller = MobileScannerController( 18 final MobileScannerController controller = MobileScannerController(
22 torchEnabled: true, 19 torchEnabled: true,
23 // formats: [BarcodeFormat.qrCode] 20 // formats: [BarcodeFormat.qrCode]
@@ -27,26 +24,10 @@ class _BarcodeScannerReturningImageState @@ -27,26 +24,10 @@ class _BarcodeScannerReturningImageState
27 returnImage: true, 24 returnImage: true,
28 ); 25 );
29 26
30 - bool isStarted = true;  
31 -  
32 - void _startOrStop() {  
33 - try {  
34 - if (isStarted) {  
35 - controller.stop();  
36 - } else {  
37 - controller.start();  
38 - }  
39 - setState(() {  
40 - isStarted = !isStarted;  
41 - });  
42 - } on Exception catch (e) {  
43 - ScaffoldMessenger.of(context).showSnackBar(  
44 - SnackBar(  
45 - content: Text('Something went wrong! $e'),  
46 - backgroundColor: Colors.red,  
47 - ),  
48 - );  
49 - } 27 + @override
  28 + void initState() {
  29 + super.initState();
  30 + controller.start();
50 } 31 }
51 32
52 @override 33 @override
@@ -57,20 +38,55 @@ class _BarcodeScannerReturningImageState @@ -57,20 +38,55 @@ class _BarcodeScannerReturningImageState
57 child: Column( 38 child: Column(
58 children: [ 39 children: [
59 Expanded( 40 Expanded(
60 - child: barcode?.image != null  
61 - ? Transform.rotate(  
62 - angle: 90 * pi / 180,  
63 - child: Image(  
64 - gaplessPlayback: true,  
65 - image: MemoryImage(barcode!.image!),  
66 - fit: BoxFit.contain,  
67 - ),  
68 - )  
69 - : const Center( 41 + child: StreamBuilder<BarcodeCapture>(
  42 + stream: controller.barcodes,
  43 + builder: (context, snapshot) {
  44 + final barcode = snapshot.data;
  45 +
  46 + if (barcode == null) {
  47 + return const Center(
70 child: Text( 48 child: Text(
71 'Your scanned barcode will appear here!', 49 'Your scanned barcode will appear here!',
72 ), 50 ),
73 - ), 51 + );
  52 + }
  53 +
  54 + final barcodeImage = barcode.image;
  55 +
  56 + if (barcodeImage == null) {
  57 + return const Center(
  58 + child: Text('No image for this barcode.'),
  59 + );
  60 + }
  61 +
  62 + return Image.memory(
  63 + barcodeImage,
  64 + fit: BoxFit.contain,
  65 + errorBuilder: (context, error, stackTrace) {
  66 + return Center(
  67 + child: Text('Could not decode image bytes. $error'),
  68 + );
  69 + },
  70 + frameBuilder: (
  71 + BuildContext context,
  72 + Widget child,
  73 + int? frame,
  74 + bool? wasSynchronouslyLoaded,
  75 + ) {
  76 + if (wasSynchronouslyLoaded == true || frame != null) {
  77 + return Transform.rotate(
  78 + angle: 90 * pi / 180,
  79 + child: child,
  80 + );
  81 + }
  82 +
  83 + return const Center(
  84 + child: CircularProgressIndicator(),
  85 + );
  86 + },
  87 + );
  88 + },
  89 + ),
74 ), 90 ),
75 Expanded( 91 Expanded(
76 flex: 2, 92 flex: 2,
@@ -84,11 +100,6 @@ class _BarcodeScannerReturningImageState @@ -84,11 +100,6 @@ class _BarcodeScannerReturningImageState
84 return ScannerErrorWidget(error: error); 100 return ScannerErrorWidget(error: error);
85 }, 101 },
86 fit: BoxFit.contain, 102 fit: BoxFit.contain,
87 - onDetect: (barcode) {  
88 - setState(() {  
89 - this.barcode = barcode;  
90 - });  
91 - },  
92 ), 103 ),
93 Align( 104 Align(
94 alignment: Alignment.bottomCenter, 105 alignment: Alignment.bottomCenter,
@@ -99,69 +110,39 @@ class _BarcodeScannerReturningImageState @@ -99,69 +110,39 @@ class _BarcodeScannerReturningImageState
99 child: Row( 110 child: Row(
100 mainAxisAlignment: MainAxisAlignment.spaceEvenly, 111 mainAxisAlignment: MainAxisAlignment.spaceEvenly,
101 children: [ 112 children: [
102 - IconButton(  
103 - color: Colors.white,  
104 - icon: ValueListenableBuilder<TorchState>(  
105 - valueListenable: controller.torchState,  
106 - builder: (context, state, child) {  
107 - switch (state) {  
108 - case TorchState.off:  
109 - return const Icon(  
110 - Icons.flash_off,  
111 - color: Colors.grey,  
112 - );  
113 - case TorchState.on:  
114 - return const Icon(  
115 - Icons.flash_on,  
116 - color: Colors.yellow,  
117 - );  
118 - }  
119 - },  
120 - ),  
121 - iconSize: 32.0,  
122 - onPressed: () => controller.toggleTorch(),  
123 - ),  
124 - IconButton(  
125 - color: Colors.white,  
126 - icon: isStarted  
127 - ? const Icon(Icons.stop)  
128 - : const Icon(Icons.play_arrow),  
129 - iconSize: 32.0,  
130 - onPressed: _startOrStop, 113 + ToggleFlashlightButton(controller: controller),
  114 + StartStopMobileScannerButton(
  115 + controller: controller,
131 ), 116 ),
132 - Center(  
133 - child: SizedBox(  
134 - width: MediaQuery.of(context).size.width - 200,  
135 - height: 50,  
136 - child: FittedBox(  
137 - child: Text(  
138 - barcode?.barcodes.first.rawValue ?? 117 + Expanded(
  118 + child: Center(
  119 + child: StreamBuilder<BarcodeCapture>(
  120 + stream: controller.barcodes,
  121 + builder: (context, snapshot) {
  122 + final barcodes = snapshot.data?.barcodes;
  123 +
  124 + if (barcodes == null || barcodes.isEmpty) {
  125 + return const Text(
139 'Scan something!', 126 'Scan something!',
140 - overflow: TextOverflow.fade,  
141 - style: Theme.of(context)  
142 - .textTheme  
143 - .headlineMedium!  
144 - .copyWith(color: Colors.white),  
145 - ), 127 + style: TextStyle(
  128 + color: Colors.white,
  129 + fontSize: 20,
  130 + ),
  131 + );
  132 + }
  133 +
  134 + return Text(
  135 + barcodes.first.rawValue ?? 'No raw value',
  136 + overflow: TextOverflow.fade,
  137 + style: const TextStyle(
  138 + color: Colors.white,
  139 + ),
  140 + );
  141 + },
146 ), 142 ),
147 ), 143 ),
148 ), 144 ),
149 - IconButton(  
150 - color: Colors.white,  
151 - icon: ValueListenableBuilder<CameraFacing>(  
152 - valueListenable: controller.cameraFacingState,  
153 - builder: (context, state, child) {  
154 - switch (state) {  
155 - case CameraFacing.front:  
156 - return const Icon(Icons.camera_front);  
157 - case CameraFacing.back:  
158 - return const Icon(Icons.camera_rear);  
159 - }  
160 - },  
161 - ),  
162 - iconSize: 32.0,  
163 - onPressed: () => controller.switchCamera(),  
164 - ), 145 + SwitchCameraButton(controller: controller),
165 ], 146 ],
166 ), 147 ),
167 ), 148 ),
@@ -177,8 +158,8 @@ class _BarcodeScannerReturningImageState @@ -177,8 +158,8 @@ class _BarcodeScannerReturningImageState
177 } 158 }
178 159
179 @override 160 @override
180 - void dispose() {  
181 - controller.dispose(); 161 + Future<void> dispose() async {
  162 + await controller.dispose();
182 super.dispose(); 163 super.dispose();
183 } 164 }
184 } 165 }