qr_barcode_dialog_scanner 1.2.2 copy "qr_barcode_dialog_scanner: ^1.2.2" to clipboard
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 #

📞 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

3
likes
150
points
46
downloads

Publisher

unverified uploader

Weekly Downloads

A Flutter package for scanning QR codes and barcodes using a dialog.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

flutter, mobile_scanner, permission_handler

More

Packages that depend on qr_barcode_dialog_scanner