Navaron Bracke

refactor a sample to use a list view instead

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_error_widget.dart';
class BarcodeListScannerWithController extends StatefulWidget {
const BarcodeListScannerWithController({super.key});
@override
State<BarcodeListScannerWithController> createState() =>
_BarcodeListScannerWithControllerState();
}
class _BarcodeListScannerWithControllerState
extends State<BarcodeListScannerWithController>
with SingleTickerProviderStateMixin {
BarcodeCapture? barcodeCapture;
final MobileScannerController controller = MobileScannerController(
torchEnabled: true,
// formats: [BarcodeFormat.qrCode]
// facing: CameraFacing.front,
// detectionSpeed: DetectionSpeed.normal
// detectionTimeoutMs: 1000,
// returnImage: false,
);
bool isStarted = true;
void _startOrStop() {
try {
if (isStarted) {
controller.stop();
} else {
controller.start();
}
setState(() {
isStarted = !isStarted;
});
} on Exception catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Something went wrong! $e'),
backgroundColor: Colors.red,
),
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('With ValueListenableBuilder')),
backgroundColor: Colors.black,
body: Builder(
builder: (context) {
return Stack(
children: [
MobileScanner(
controller: controller,
errorBuilder: (context, error, child) {
return ScannerErrorWidget(error: error);
},
fit: BoxFit.contain,
onDetect: (barcodeCapture) {
setState(() {
this.barcodeCapture = barcodeCapture;
});
},
onScannerStarted: (arguments) {
// Do something with arguments.
},
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
alignment: Alignment.bottomCenter,
height: 100,
color: Colors.black.withOpacity(0.4),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
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,
),
Center(
child: SizedBox(
width: MediaQuery.of(context).size.width - 200,
height: 50,
child: FittedBox(
child: Text(
'${barcodeCapture?.barcodes.map((e) => e.rawValue) ?? 'Scan something!'}',
overflow: TextOverflow.fade,
style: Theme.of(context)
.textTheme
.headlineMedium!
.copyWith(color: Colors.white),
),
),
),
),
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: () => 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,
),
);
}
}
},
),
],
),
),
),
],
);
},
),
);
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
}
import 'dart:async';
import 'package:flutter/material.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 BarcodeScannerListView extends StatefulWidget {
const BarcodeScannerListView({super.key});
@override
State<BarcodeScannerListView> createState() => _BarcodeScannerListViewState();
}
class _BarcodeScannerListViewState extends State<BarcodeScannerListView> {
final MobileScannerController controller = MobileScannerController(
torchEnabled: true,
// formats: [BarcodeFormat.qrCode]
// facing: CameraFacing.front,
// detectionSpeed: DetectionSpeed.normal
// detectionTimeoutMs: 1000,
// returnImage: false,
);
@override
void initState() {
super.initState();
controller.start();
}
Widget _buildBarcodesListView() {
return StreamBuilder<BarcodeCapture>(
stream: controller.barcodes,
builder: (context, snapshot) {
final barcodes = snapshot.data?.barcodes;
if (barcodes == null || barcodes.isEmpty) {
return const Center(
child: Text(
'Scan Something!',
style: TextStyle(color: Colors.white, fontSize: 20),
),
);
}
return ListView.builder(
itemCount: barcodes.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
barcodes[index].rawValue ?? 'No raw value',
overflow: TextOverflow.fade,
style: const TextStyle(color: Colors.white),
),
);
},
);
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('With ListView')),
backgroundColor: Colors.black,
body: Stack(
children: [
MobileScanner(
controller: controller,
errorBuilder: (context, error, child) {
return ScannerErrorWidget(error: error);
},
fit: BoxFit.contain,
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
alignment: Alignment.bottomCenter,
height: 100,
color: Colors.black.withOpacity(0.4),
child: Column(
children: [
Expanded(
child: _buildBarcodesListView(),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ToggleFlashlightButton(controller: controller),
StartStopMobileScannerButton(controller: controller),
const Spacer(),
SwitchCameraButton(controller: controller),
AnalyzeImageFromGalleryButton(controller: controller),
],
),
],
),
),
),
],
),
);
}
@override
Future<void> dispose() async {
await controller.dispose();
super.dispose();
}
}
... ...
import 'package:flutter/material.dart';
import 'package:mobile_scanner_example/barcode_list_scanner_controller.dart';
import 'package:mobile_scanner_example/barcode_scanner_controller.dart';
import 'package:mobile_scanner_example/barcode_scanner_listview.dart';
import 'package:mobile_scanner_example/barcode_scanner_pageview.dart';
import 'package:mobile_scanner_example/barcode_scanner_returning_image.dart';
import 'package:mobile_scanner_example/barcode_scanner_window.dart';
... ... @@ -33,12 +33,11 @@ class MyHome extends StatelessWidget {
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) =>
const BarcodeListScannerWithController(),
builder: (context) => const BarcodeScannerListView(),
),
);
},
child: const Text('MobileScanner with List Controller'),
child: const Text('MobileScanner with ListView'),
),
ElevatedButton(
onPressed: () {
... ...