Create a barcode scanner in FlutterFlow using a Custom Widget with the mobile_scanner package. Initialize MobileScannerController with back camera and normal detection speed. Handle the onDetect callback to extract barcode.rawValue and pass the scanned result to the parent via an Action Parameter callback. Add a scanner frame overlay using a Stack with a transparent center rectangle for visual targeting.
Building a Barcode and QR Code Scanner in FlutterFlow
Barcode scanning is essential for inventory management, retail apps, event ticketing, and product lookup. FlutterFlow does not have a built-in scanner widget, so you need a Custom Widget using the mobile_scanner package. This tutorial covers the full implementation including camera setup, barcode detection, overlay UI, and data passing.
Prerequisites
- FlutterFlow Pro plan or higher (Custom Code required)
- A FlutterFlow project open in the builder
- A physical device for testing (camera does not work in simulator)
- Camera permissions configured in your app settings
Step-by-step guide
Add the mobile_scanner dependency to your project
Add the mobile_scanner dependency to your project
Navigate to Custom Code in the left Navigation Menu and click the Pubspec Dependencies tab. Add mobile_scanner with version ^5.0.0. Click Save. This package is the recommended successor to qr_code_scanner and supports QR codes, UPC, EAN, Code128, and all major barcode formats on both iOS and Android.
Expected result: The mobile_scanner package appears in your Pubspec Dependencies without errors.
Create the Custom Widget with MobileScannerController
Create the Custom Widget with MobileScannerController
Go to Custom Code → Custom Widgets → Add. Name it BarcodeScannerWidget. Add parameters: onBarcodeScanned (Action, required) to pass the result back to the parent. In the code editor, create a StatefulWidget. In initState, create a MobileScannerController with detectionSpeed set to DetectionSpeed.normal, facing set to CameraFacing.back, and torchEnabled set to false. In build, return a MobileScanner widget with the controller and an onDetect callback that extracts the barcode value.
1import 'package:mobile_scanner/mobile_scanner.dart';23class BarcodeScannerWidget extends StatefulWidget {4 const BarcodeScannerWidget({5 super.key,6 this.width,7 this.height,8 required this.onBarcodeScanned,9 });10 final double? width;11 final double? height;12 final Future Function(String barcodeValue) onBarcodeScanned;1314 @override15 State<BarcodeScannerWidget> createState() => _BarcodeScannerWidgetState();16}1718class _BarcodeScannerWidgetState extends State<BarcodeScannerWidget> {19 final MobileScannerController _controller = MobileScannerController(20 detectionSpeed: DetectionSpeed.normal,21 facing: CameraFacing.back,22 torchEnabled: false,23 );24 bool _hasScanned = false;2526 @override27 void dispose() {28 _controller.dispose();29 super.dispose();30 }3132 @override33 Widget build(BuildContext context) {34 return SizedBox(35 width: widget.width ?? double.infinity,36 height: widget.height ?? 400,37 child: MobileScanner(38 controller: _controller,39 onDetect: (capture) {40 if (_hasScanned) return;41 final barcode = capture.barcodes.firstOrNull;42 if (barcode?.rawValue != null) {43 _hasScanned = true;44 widget.onBarcodeScanned(barcode!.rawValue!);45 }46 },47 ),48 );49 }50}Expected result: The Custom Widget compiles and detects barcodes via the camera feed.
Add a scanner frame overlay with a transparent center target area
Add a scanner frame overlay with a transparent center target area
Wrap the MobileScanner in a Stack. Add a second child to the Stack: a CustomPaint or a Column of Containers creating a darkened overlay with a transparent rectangular cutout in the center. The cutout acts as a visual target — users aim the barcode within this frame. Use Container widgets with semi-transparent black background around the edges, leaving the center open. Add a thin border Container (2px, white) around the cutout for the scanning frame indicator.
Expected result: A darkened overlay with a clear center rectangle shows over the camera preview, guiding where to aim the barcode.
Add a torch toggle button and result display
Add a torch toggle button and result display
Below or overlaying the scanner, add an IconButton for torch/flash toggle. On Tap, call controller.toggleTorch(). Use a StreamBuilder on controller.torchState to toggle the icon between flash_on and flash_off. Below the scanner, add a Text widget bound to a Page State variable scannedResult that updates when the onBarcodeScanned callback fires. After scanning, you can automatically navigate to a product detail page or show the result in a dialog.
Expected result: Users can toggle the flashlight for low-light scanning and see the scanned barcode value displayed on screen.
Handle the scanned result in the parent page action flow
Handle the scanned result in the parent page action flow
On the page where you placed the BarcodeScannerWidget, bind the onBarcodeScanned Action Parameter to an action flow. In the flow: update Page State scannedResult with the barcode value, then either navigate to a lookup page passing the value as a Route Parameter, or call an API/Backend Query to look up the product by barcode. Add a reset mechanism — a Scan Again button that sets _hasScanned back to false (via a Custom Action calling a method on the widget, or by rebuilding the widget).
Expected result: Scanned barcode data flows from the Custom Widget to the parent page for display or database lookup.
Complete working example
1import 'package:mobile_scanner/mobile_scanner.dart';23class BarcodeScannerWidget extends StatefulWidget {4 const BarcodeScannerWidget({5 super.key,6 this.width,7 this.height,8 required this.onBarcodeScanned,9 });1011 final double? width;12 final double? height;13 final Future Function(String barcodeValue) onBarcodeScanned;1415 @override16 State<BarcodeScannerWidget> createState() => _BarcodeScannerWidgetState();17}1819class _BarcodeScannerWidgetState extends State<BarcodeScannerWidget> {20 final MobileScannerController _controller = MobileScannerController(21 detectionSpeed: DetectionSpeed.normal,22 facing: CameraFacing.back,23 torchEnabled: false,24 );25 bool _hasScanned = false;2627 @override28 void dispose() {29 _controller.dispose();30 super.dispose();31 }3233 void _onDetect(BarcodeCapture capture) {34 if (_hasScanned) return;35 final barcode = capture.barcodes.firstOrNull;36 if (barcode?.rawValue == null) return;37 setState(() => _hasScanned = true);38 widget.onBarcodeScanned(barcode!.rawValue!);39 }4041 @override42 Widget build(BuildContext context) {43 return SizedBox(44 width: widget.width ?? double.infinity,45 height: widget.height ?? 400,46 child: Stack(47 children: [48 MobileScanner(49 controller: _controller,50 onDetect: _onDetect,51 ),52 // Overlay with transparent center53 Center(54 child: Container(55 width: 250,56 height: 250,57 decoration: BoxDecoration(58 border: Border.all(color: Colors.white, width: 2),59 borderRadius: BorderRadius.circular(12),60 ),61 ),62 ),63 // Torch toggle button64 Positioned(65 bottom: 16,66 right: 16,67 child: IconButton(68 icon: const Icon(Icons.flash_on, color: Colors.white, size: 28),69 onPressed: () => _controller.toggleTorch(),70 ),71 ),72 ],73 ),74 );75 }76}Common mistakes when creating a Barcode Scanner in FlutterFlow
Why it's a problem: Using the deprecated qr_code_scanner package
How to avoid: Use mobile_scanner (version 5.x) which is actively maintained, supports all barcode formats, and works with current Flutter versions.
Why it's a problem: Not preventing multiple scans of the same barcode
How to avoid: Add a boolean _hasScanned flag that blocks further callbacks after the first successful detection. Reset it when the user wants to scan again.
Why it's a problem: Testing barcode scanning in the iOS simulator or FlutterFlow preview
How to avoid: Test barcode scanning on a physical iOS or Android device. Use Run mode or a test APK/IPA build.
Best practices
- Use mobile_scanner package version 5.x for the most reliable barcode detection
- Add a visual scanner frame overlay to guide users where to aim the camera
- Prevent duplicate scans with a boolean flag that blocks callbacks after first detection
- Include a torch/flash toggle button for scanning in low-light environments
- Always dispose the MobileScannerController in the widget's dispose method
- Test on physical devices — camera scanning does not work in simulators
- Handle the case where camera permission is denied with a friendly message and settings link
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
Write a FlutterFlow Custom Widget for barcode and QR code scanning using the mobile_scanner package. Include camera preview, onDetect callback that passes the barcode value to the parent, a scanner frame overlay, torch toggle, and duplicate scan prevention.
Create a page with a full-width container at 400px height for a barcode scanner, a text display below it for the scanned result, and a button to scan again.
Frequently asked questions
What barcode formats does mobile_scanner support?
mobile_scanner supports QR Code, UPC-A, UPC-E, EAN-8, EAN-13, Code 39, Code 93, Code 128, ITF, Codabar, Data Matrix, Aztec, and PDF417.
Can the scanner read barcodes from images instead of the live camera?
Yes. mobile_scanner supports analyzing static images via MobileScannerController.analyzeImage(path). The user selects an image and the scanner detects barcodes in it.
Does the barcode scanner work on web?
mobile_scanner has limited web support using the device webcam. It works best on mobile (iOS and Android) where it uses the native camera APIs.
How do I scan only QR codes and ignore other barcode types?
In the onDetect callback, check barcode.format. Only process the result if format equals BarcodeFormat.qrCode. Ignore other formats by returning early.
Can I customize the scanner overlay frame size?
Yes. The overlay is just a Container with a border. Change the width and height to match the barcode size you expect — larger for QR codes, narrower for linear barcodes.
Can RapidDev help build a scanning workflow for my business?
Yes. RapidDev can build end-to-end scanning workflows including barcode detection, product database lookup, inventory management, and receipt generation.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation