qr_scanner_kit 0.2.0
qr_scanner_kit: ^0.2.0 copied to clipboard
A ready-to-use QR scanner screen and viewfinder overlay built on mobile_scanner, with torch, camera switching, and a simple scan callback.
qr_scanner_kit #
A ready-to-use QR scanner screen and viewfinder overlay built on
mobile_scanner, with torch
control, camera switching, and a simple scan callback. The package comes from
the Rocketbot app, so every scanner screen behaves the same.
Features #
QrScanner: a full-screen scanner with a live camera preview- Torch toggle and front/back camera switching in the app bar
QrImageScanner: gallery scanning from an image file- Barcode format selection through
formats - Haptic feedback on accepted scans
- Validation hooks:
isAcceptedandonRejected BarcodeOverlay: aShapeBorderthat dims the preview and draws corner brackets around a centered cut-outScanGate: a helper that lets a callback run at most once- One-shot
onScancallback withpopOnScancontrol - Optional injection of a
MobileScannerController - No state-management dependency, only plain Flutter widgets
Install #
flutter pub add qr_scanner_kit
Permissions #
mobile_scanner needs camera access at runtime.
Android #
mobile_scanner merges the CAMERA permission from its own manifest and
requests it at runtime. No app-side change is necessary. When the app handles
permission UX itself, request the permission before you push QrScanner.
iOS #
Add a usage description to ios/Runner/Info.plist. App Review rejects the app
without this entry:
<key>NSCameraUsageDescription</key>
<string>This app needs camera access to scan QR codes.</string>
Usage #
import 'package:flutter/material.dart';
import 'package:qr_scanner_kit/qr_scanner_kit.dart';
Navigator.of(context).push(
MaterialPageRoute<void>(
builder: (BuildContext context) {
return QrScanner(
title: 'Scan QR code',
onScan: (String value) {
print('Scanned: $value');
},
);
},
),
);
Gallery scanning #
QrImageScanner.scanImageFile decodes one barcode from an image file:
final String? value = await QrImageScanner.scanImageFile('/path/to/code.png');
The method creates its own controller, analyzes the file, and disposes the
controller. A running camera scan keeps its state. Image analysis works on
Android, physical iOS devices, and macOS. Unsupported platforms throw an
UnsupportedError. The iOS Simulator does not support image analysis.
Barcode formats #
By default, QrScanner detects all barcode formats. Pass formats to limit
detection to specific formats. The list goes to the internally created
controller:
import 'package:mobile_scanner/mobile_scanner.dart';
QrScanner(
formats: const [BarcodeFormat.qrCode, BarcodeFormat.ean13],
onScan: (String value) {
print('Scanned: $value');
},
);
An injected controller keeps its own formats. The formats parameter has no
effect on an injected controller.
Haptics #
QrScanner plays a light haptic impact when it accepts a code. Haptics are on
by default. Set hapticsEnabled: false to disable them:
QrScanner(
hapticsEnabled: false,
onScan: (String value) {
print('Scanned: $value');
},
);
Validation hooks #
Use isAccepted to filter scanned values. The scanner checks isAccepted
before the one-shot gate. A rejected value consumes no scan attempt, fires no
haptics, and calls no onScan. The scanner stays ready for the next code and
reports rejected values through onRejected:
QrScanner(
isAccepted: (String value) => value.startsWith('SHOP-'),
onRejected: (String value) => print('Rejected: $value'),
onScan: (String value) => print('Accepted: $value'),
);
API #
QrScanner #
| Parameter | Type | Default | Purpose |
|---|---|---|---|
onScan |
ValueChanged<String> |
required | Receives the first decoded non-empty barcode value. |
title |
String? |
'Scan QR code' |
App bar title. |
overlay |
BarcodeOverlay? |
red corner brackets | Overlay on the camera preview. |
backgroundColor |
Color? |
Theme.canvasColor |
Background color of the scanner body. |
popOnScan |
bool |
true |
Pops the route after the first scan. |
controller |
MobileScannerController? |
created internally | Camera controller. The widget respects its autoStart flag. |
formats |
List<BarcodeFormat>? |
null (all formats) |
Formats for the internally created controller. |
hapticsEnabled |
bool |
true |
Plays a light haptic impact on an accepted scan. |
isAccepted |
bool Function(String)? |
null (accept all) |
Filters values before the one-shot gate. |
onRejected |
void Function(String)? |
null |
Receives values that isAccepted rejects. |
onScan runs at most once per QrScanner. The widget reports only the first
decoded non-empty barcode and then cancels the subscription. With
popOnScan: false, the screen stays open but reports no more barcodes. Push a
new QrScanner to scan again.
When you do not pass a controller, QrScanner creates one with
autoStart: false. The widget starts and stops the controller with the app
lifecycle and disposes it. Do not dispose an injected controller yourself. Do
not reuse it after the scanner closes. To inject a controller, import
package:mobile_scanner/mobile_scanner.dart. The package does not re-export
mobile_scanner.
QrImageScanner #
QrImageScanner.scanImageFile(path) decodes one barcode from an image file
and returns its value. It returns null when the image holds no barcode. The
method creates its own controller and disposes the controller after the scan.
A running camera scan keeps its state. Image analysis works on Android,
physical iOS devices, and macOS. Unsupported platforms throw an
UnsupportedError.
BarcodeOverlay #
| Parameter | Default | Purpose |
|---|---|---|
borderColor |
Colors.red |
Color of the corner brackets. |
borderWidth |
3.0 |
Stroke width of the corner brackets. |
overlayColor |
translucent black | Dim color outside the cut-out. |
borderRadius |
0 |
Corner radius of the cut-out and brackets. |
borderLength |
40 |
Length of each corner bracket. |
cutOutSize, cutOutWidth, cutOutHeight |
250 | Cut-out dimensions. |
cutOutBottomOffset |
0 |
Vertical offset of the cut-out. |
Use cutOutSize, or use cutOutWidth and cutOutHeight. Do not use both.
ScanGate #
ScanGate holds the one-shot guard as a small, testable helper. tryHandle()
returns true once and false on later calls until you call reset().
Example #
A runnable app in example/ pushes the scanner and shows the last
scanned value. The example ships without platform folders, so generate them
before you run it on a device with a camera:
cd example
flutter create . --platforms=android,ios
flutter run
Attribution #
BarcodeOverlay is a modified copy of OverlayShape from the
ai_barcode_scanner package
(version 5.2.2, Apache-2.0). It was renamed, documented, and adjusted. The
full Apache-2.0 license text is in THIRD_PARTY_NOTICES.
The package itself is MIT licensed. See LICENSE. Only the derived
BarcodeOverlay remains under Apache-2.0.