qr_barcode_dialog_scanner 1.2.2
qr_barcode_dialog_scanner: ^1.2.2 copied to clipboard
A Flutter package for scanning QR codes and barcodes using a dialog.
qr_barcode_dialog_scanner #
A modern and elegant Flutter package for QR Code and Barcode scanning with a dialog interface and smooth UX. version 1.2.2
✨ Features #
- 🎨 Modern UI Design - Beautiful dialog with glass morphism effects and smooth animations
- 📱 Complete Barcode Support - QR Code, EAN-13, Code 128, and 15+ barcode formats
- 💡 Flash Control - Elegant toggle for flashlight with visual feedback
- 📷 Camera Switch - Seamless front/rear camera switching
- 🎭 Custom Dialog - Fully customizable dialog with premium animations
- 🔒 Auto Permissions - Automatic camera permission handling
- ⏱️ Timeout Support - Configurable scanning timeout
- 🎵 Haptic Feedback - Native vibration on successful scan
- 🌙 Dark Mode Ready - Beautiful dark theme with custom colors
- 🚀 High Performance - Optimized for smooth 60fps scanning
- 📊 Multiple Formats - Support for all major barcode standards
- 🔄 Real-time Scanning - Live scanning with animated scan line
📦 Installation #
Add this to your package's pubspec.yaml
file:
dependencies:
qr_barcode_dialog_scanner: ^1.2.2
Then run:
flutter pub get
🚀 Quick Start #
Basic Usage #
import 'package:qr_barcode_dialog_scanner/qr_barcode_dialog_scanner.dart';
// Simple scan
final result = await QRBarcodeScanner.showScannerDialog(context);
if (result != null) {
print('Scanned: ${result.code}');
print('Format: ${result.format}');
print('Time: ${result.timestamp}');
}
Advanced Usage with Customization #
final result = await QRBarcodeScanner.showScannerDialog(
context,
title: 'Scan Product',
subtitle: 'Place the barcode inside the frame',
primaryColor: Colors.deepPurple,
backgroundColor: Colors.black87,
allowFlashToggle: true,
allowCameraToggle: true,
timeout: Duration(minutes: 2),
);
if (result != null) {
// Handle different barcode types
switch (result.format) {
case BarcodeFormat.qrcode:
_handleQRCode(result.code);
break;
case BarcodeFormat.ean13:
_handleProductBarcode(result.code);
break;
case BarcodeFormat.code128:
_handleShippingCode(result.code);
break;
default:
_handleGenericCode(result.code);
}
}
🔐 Platform Setup #
Android Configuration #
Add these permissions to android/app/src/main/AndroidManifest.xml
:
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature
android:name="android.hardware.camera"
android:required="true" />
<uses-feature
android:name="android.hardware.camera.autofocus"
android:required="false" />
iOS Configuration #
Add camera usage description to ios/Runner/Info.plist
:
<key>NSCameraUsageDescription</key>
<string>This app needs camera access to scan QR codes and barcodes</string>
For iOS 10.0+, also add:
<key>NSPhotoLibraryUsageDescription</key>
<string>This app needs photo library access to scan codes from images</string>
🎨 Customization Guide #
Colors and Theme #
await QRBarcodeScanner.showScannerDialog(
context,
// Primary color for UI elements
primaryColor: Color(0xFF6C63FF),
// Dialog background color
backgroundColor: Colors.black87,
);
Custom Titles #
await QRBarcodeScanner.showScannerDialog(
context,
title: 'Custom Scanner',
subtitle: 'Scan your code here',
);
Feature Control #
await QRBarcodeScanner.showScannerDialog(
context,
// Enable/disable flash toggle
allowFlashToggle: true,
// Enable/disable camera switching
allowCameraToggle: false,
// Auto-close dialog after timeout
timeout: Duration(seconds: 30),
);
📱 Practical Examples #
1. QR Code URL Scanner #
void scanQRForURL() async {
final result = await QRBarcodeScanner.showScannerDialog(
context,
title: 'Scan QR Code',
subtitle: 'Point camera at QR code to open link',
primaryColor: Colors.blue,
// Currently scans all supported formats by mobile_scanner
);
if (result != null && _isValidURL(result.code)) {
await launch(result.code);
} else {
_showErrorDialog('Invalid URL in QR code');
}
}
bool _isValidURL(String url) {
return Uri.tryParse(url)?.hasAbsolutePath ?? false;
}
2. Product Barcode Scanner #
void scanProductBarcode() async {
final result = await QRBarcodeScanner.showScannerDialog(
context,
title: 'Scan Product',
subtitle: 'Scan barcode to view product details',
primaryColor: Colors.green,
allowCameraToggle: false,
// Scans common product codes (EAN/UPC) automatically
);
if (result != null) {
final product = await _fetchProductDetails(result.code);
if (product != null) {
_showProductDialog(product);
} else {
_showErrorDialog('Product not found');
}
}
}
3. WiFi QR Code Scanner #
void scanWiFiQR() async {
final result = await QRBarcodeScanner.showScannerDialog(
context,
title: 'Connect to WiFi',
subtitle: 'Scan WiFi QR code to connect',
primaryColor: Colors.teal,
timeout: Duration(minutes: 1),
);
if (result != null && result.code.startsWith('WIFI:')) {
final wifiConfig = _parseWiFiQR(result.code);
await _connectToWiFi(wifiConfig);
}
}
Map<String, String> _parseWiFiQR(String qrData) {
// Parse WIFI:T:WPA;S:MyNetwork;P:MyPassword;H:false;;
final params = <String, String>{};
final parts = qrData.substring(5).split(';');
for (final part in parts) {
if (part.contains(':')) {
final keyValue = part.split(':');
params[keyValue[0]] = keyValue[1];
}
}
return params;
}
4. Document Scanner with Validation #
void scanDocumentQR() async {
final result = await QRBarcodeScanner.showScannerDialog(
context,
title: 'Scan Document',
subtitle: 'Scan document QR for verification',
primaryColor: Colors.orange,
timeout: Duration(seconds: 45),
);
if (result != null) {
final isValid = await _validateDocument(result.code);
if (isValid) {
_showSuccessDialog('Document verified successfully');
} else {
_showErrorDialog('Invalid or expired document');
}
}
}
🔧 Complete API Reference #
QRBarcodeScanner #
showScannerDialog()
static Future<ScannerResult?> showScannerDialog(
BuildContext context, {
// UI Customization
String? title, // Dialog title
String? subtitle, // Dialog subtitle
Color? primaryColor, // Primary theme color
Color? backgroundColor, // Background color
Gradient? backgroundGradient, // Custom gradient
// Feature Control
bool allowFlashToggle = true, // Enable flash control
bool allowCameraToggle = true, // Enable camera switching
List<BarcodeFormat>? allowedFormats, // Restrict barcode types
// Timing
Duration? timeout, // Auto-close timeout
// Messages
String? successMessage, // Success feedback
String? errorMessage, // Error feedback
// Callbacks
void Function(String)? onCodeScanned, // Real-time scan callback
void Function()? onTimeout, // Timeout callback
// Animation Control
bool enableAnimations = true, // Enable/disable animations
Duration animationDuration = const Duration(milliseconds: 300),
})
Permission Methods
// Request camera permission
static Future<bool> requestCameraPermission()
// Check if permission is granted
static Future<bool> isCameraPermissionGranted()
ScannerResult Class #
class ScannerResult {
final String code; // Scanned code content
final BarcodeFormat format; // Barcode format type
final DateTime timestamp; // Scan timestamp
final List<Offset>? corners; // Code corner positions (if available)
// Utility Methods
Map<String, dynamic> toJson(); // Convert to JSON
factory ScannerResult.fromJson(Map json); // Create from JSON
ScannerResult copyWith({...}); // Create copy with changes
// Format Checking
bool get isQRCode => format == BarcodeFormat.qrcode;
bool get isEAN13 => format == BarcodeFormat.ean13;
bool get isProductCode => [BarcodeFormat.ean13, BarcodeFormat.ean8, BarcodeFormat.upca].contains(format);
}
BarcodeFormat Enum #
enum BarcodeFormat {
unknown, // Unknown format
qrcode, // QR Code
ean13, // EAN-13 (product barcodes)
ean8, // EAN-8
upca, // UPC-A
upce, // UPC-E
code39, // Code 39
code93, // Code 93
code128, // Code 128
itf, // ITF (Interleaved 2 of 5)
codabar, // Codabar
pdf417, // PDF417
dataMatrix, // Data Matrix
aztec, // Aztec Code
}
� Example: BuildScannerArea (custom scanner area) #
Arabic (Iraqi): هذا مثال موجود داخل التطبيق التجريبي يبين شلون تسوي واجهة مسح مخصصة باستخدام MobileScanner. مو جزء من الحزمة نفسها، لكن تگدر تنسخه وتعدله حسب حاجتك. إذا تريد حل جاهز وسريع، استخدم الدالة الجاهزة QRBarcodeScanner.showScannerDialog.
English: This is an example widget in the example app that demonstrates building a custom scanning UI using MobileScanner. It is not exported by the package; copy and adapt it if you need full UI control. For the quickest integration, prefer QRBarcodeScanner.showScannerDialog.
Location: example/lib/src/BuildScannerArea.dart
Parameters
- title, subtitle: Dialog texts shown above the scan area
- primaryColor, backgroundColor: Accent and background colors for the visuals
- allowFlashToggle, allowCameraToggle: Enable/disable flash and camera switch buttons
- timeout: Optional auto-close duration
- onResult(String code): Callback invoked with the first detected code value
Quick usage (inside the example app)
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => BuildScannerArea(
title: 'Barcode Scanner',
subtitle: 'Place the code inside the frame',
primaryColor: Colors.deepPurple,
backgroundColor: Colors.black87,
allowFlashToggle: true,
allowCameraToggle: true,
onResult: (code) {
// Handle the result, then close the screen
debugPrint('Scanned: $code');
Navigator.of(context).pop();
},
),
),
);
Notes
- Uses MobileScanner directly with a styled overlay and simple animations.
- Returns only the first detected code via onResult.
- For most apps, the package dialog API is simpler: QRBarcodeScanner.showScannerDialog(context, ...).
�🛠️ Advanced Features #
Custom Scanning Overlay #
class CustomScannerOverlay extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Stack(
children: [
// Custom scanning frame
Center(
child: Container(
width: 250,
height: 250,
decoration: BoxDecoration(
border: Border.all(color: Colors.white, width: 2),
borderRadius: BorderRadius.circular(12),
),
),
),
// Custom instructions
Positioned(
bottom: 100,
left: 0,
right: 0,
child: Text(
'Align code within the frame',
style: TextStyle(color: Colors.white),
textAlign: TextAlign.center,
),
),
],
);
}
}
Batch Scanning #
class BatchScanner {
final List<ScannerResult> _scannedCodes = [];
void startBatchScanning() async {
while (_scannedCodes.length < 10) {
final result = await QRBarcodeScanner.showScannerDialog(
context,
title: 'Batch Scan (${_scannedCodes.length + 1}/10)',
onCodeScanned: (code) {
// Validate before adding
if (!_scannedCodes.any((r) => r.code == code)) {
_scannedCodes.add(ScannerResult(
code: code,
format: BarcodeFormat.unknown,
timestamp: DateTime.now(),
));
}
},
);
if (result == null) break; // User cancelled
}
_processBatchResults(_scannedCodes);
}
}
🎯 Supported Barcode Types #
Format | Description | Common Use Cases |
---|---|---|
QR Code | 2D matrix barcode | URLs, WiFi configs, contact info |
EAN-13 | European Article Number | Product identification |
EAN-8 | Shorter EAN format | Small products |
UPC-A | Universal Product Code | North American products |
UPC-E | Compressed UPC | Small package products |
Code 39 | Alphanumeric linear | Industrial applications |
Code 93 | Extended ASCII | Logistics, inventory |
Code 128 | High-density linear | Shipping, packaging |
ITF | Interleaved 2 of 5 | Cartons, packaging |
Codabar | Numeric + special chars | Libraries, blood banks |
PDF417 | 2D stacked linear | ID cards, transport |
Data Matrix | 2D matrix | Small item marking |
Aztec | 2D matrix | Transport tickets |
Camera Permission Denied
// Check and request permission before scanning
if (!await QRBarcodeScanner.isCameraPermissionGranted()) {
final granted = await QRBarcodeScanner.requestCameraPermission();
if (!granted) {
// Show dialog to open app settings
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('Camera Permission Required'),
content: Text('Please enable camera permission in app settings'),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: Text('Open Settings'),
),
],
),
);
return;
}
}
Performance Issues
// Use timeout to prevent battery drain
await QRBarcodeScanner.showScannerDialog(
context,
timeout: Duration(minutes: 1),
onTimeout: () {
print('Scanning timed out');
},
);
// Limit allowed formats for faster scanning
await QRBarcodeScanner.showScannerDialog(
context,
allowedFormats: [BarcodeFormat.qrcode], // Only scan QR codes
);
Multiple Dialog Issue
// Prevent multiple dialogs
bool _isScanning = false;
void startScanning() async {
if (_isScanning) return;
_isScanning = true;
try {
final result = await QRBarcodeScanner.showScannerDialog(context);
// Handle result
} finally {
_isScanning = false;
}
}
Invalid Barcode Handling
void scanWithValidation() async {
final result = await QRBarcodeScanner.showScannerDialog(
context,
onCodeScanned: (code) {
// Real-time validation
if (!_isValidCode(code)) {
// Show error feedback
HapticFeedback.heavyImpact();
return;
}
},
);
if (result != null && _isValidCode(result.code)) {
_processValidCode(result);
} else {
_showInvalidCodeError();
}
}
📋 System Requirements #
- Flutter SDK: ≥ 3.0.0
- Dart SDK: ≥ 2.19.0
- Android: API level 21+ (Android 5.0+)
- iOS: 11.0+
- Camera: Required for scanning functionality
📄 License #
This project is licensed under the MIT License - see the LICENSE file for details.
🙏 Acknowledgments #
- mobile_scanner - Core scanning functionality
- permission_handler - Permission management
- Flutter team for the amazing framework
📞 Support #
- 📧 Email Support: amhmeed31@gmail.com
- 🐙 GitHub Issues: Open an issue if you encounter a bug or have a feature request
📄 License #
MIT © 2025 Ahmed Shaker
Made with ❤️ for the Flutter community