multi_qr_tracker 0.5.0 copy "multi_qr_tracker: ^0.5.0" to clipboard
multi_qr_tracker: ^0.5.0 copied to clipboard

A Flutter package for detecting and tracking multiple QR codes simultaneously on Android and iOS with adaptive UI overlays. Native CameraX and AVFoundation implementation.

multi_qr_tracker #

pub package License: MIT

A powerful Flutter package for detecting and tracking multiple QR codes simultaneously with adaptive UI overlays.

Platform Support Orientation Support

๐ŸŽฏ Why This Package? #

This package was created to provide reliable multi-QR code detection with native implementations using CameraX (Android) and AVFoundation (iOS).

Current Status:

  • โœ… Android platform support
  • โœ… iOS platform support
  • โœ… Portrait orientation
  • ๐Ÿšง Landscape orientation coming in future updates

Multi QR Tracker Demo

โœจ Features #

  • ๐Ÿ” Multi-QR Code Detection: Detect and track multiple QR codes simultaneously in real-time
  • ๐Ÿ“ Dynamic Borders: Borders automatically adjust size as you move closer or further from QR codes
  • ๐Ÿ”„ Rotated Border Rendering: Borders rotate to match QR code orientation at any angle
  • ๐ŸŽจ Smart Border Coloring: Fixed color or auto-mode (same QR value = same color)
  • ๐ŸŽฏ Adaptive Scan Buttons: Full buttons with icon and text for large QR codes, icon-only for small ones
  • ๐Ÿ”ฆ Smart Torch Control: Three modes - off, auto (turns on in dark), or manual button control
  • โฑ๏ธ Automatic Scanning: Configurable auto-scan after delay (default 2 seconds, can disable)
  • ๐ŸŽฎ Camera Lifecycle Control: Optional controller for start/stop and battery optimization
  • ๐ŸŽฏ Optional Scan Frame: Show corner indicators to guide users where to position QR codes
  • ๐ŸŽจ Fully Customizable: Colors, border width, padding, corner radius, scan frame style, and more
  • ๐Ÿš€ High Performance: Smooth real-time tracking with CameraX and ML Kit Barcode Scanning
  • ๐Ÿ” Zero Setup Required: Automatic permission handling - no AndroidManifest.xml configuration needed
  • ๐Ÿค– Native Implementation: CameraX (Android) and AVFoundation (iOS) for optimal performance
  • ๐Ÿ“ฑ Current Support: Android (API 21+) and iOS (13.0+) in portrait orientation
  • ๐Ÿ”ฎ Coming Soon: Landscape orientation

๐Ÿ“ฑ Screenshots #

Fixed Border Color
With borderColor
All borders use specified color
Auto Color per QR Code
Without borderColor
Auto colors (same QR = same color)

๐Ÿš€ Getting Started #

Installation #

Add this to your package's pubspec.yaml file:

dependencies:
  multi_qr_tracker: ^0.5.0

Then run:

flutter pub get

Platform Setup #

Android

No manual setup required! The package automatically:

  • โœ… Declares camera permissions in the manifest (merged automatically)
  • โœ… Requests runtime camera permissions when needed
  • โœ… Handles permission results

Just ensure your minimum SDK version is 21 or higher in android/app/build.gradle:

minSdkVersion 21

iOS

Add the NSCameraUsageDescription key to your ios/Runner/Info.plist file. This explains why your app needs camera access:

<key>NSCameraUsageDescription</key>
<string>This app needs camera access to scan QR codes</string>

๐Ÿ’ก Usage #

Basic Example #

import 'package:flutter/material.dart';
import 'package:multi_qr_tracker/multi_qr_tracker.dart';

class QRScannerPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('QR Scanner')),
      body: MultiQrTrackerView(
        onQrCodeScanned: (String value) {
          print('Scanned: $value');
          // Handle scanned QR code
        },
        // Auto-scan enabled by default after 2 seconds
      ),
    );
  }
}

Border Color Modes #

// Fixed color - all borders use specified color
MultiQrTrackerView(
  onQrCodeScanned: (value) => print(value),
  borderColor: Colors.green, // All borders green
)

// Auto color mode - same QR value gets same color
MultiQrTrackerView(
  onQrCodeScanned: (value) => print(value),
  // borderColor: null (default), generates unique colors
)

Camera Control with Controller #

class _ScannerScreenState extends State<ScannerScreen> {
  final _controller = MultiQrTrackerController();

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  void _navigateToDetails() {
    // Stop camera when navigating away (saves battery)
    _controller.stop();
    Navigator.push(context, /* ... */);
  }

  void _onReturn() {
    // Resume camera when returning
    _controller.start();
  }

  @override
  Widget build(BuildContext context) {
    return MultiQrTrackerView(
      controller: _controller,
      onQrCodeScanned: (value) => print(value),
    );
  }
}

Benefits of using a controller:

  • ๐Ÿ”‹ Battery Saving: Stop camera when not visible (tabs, modals, navigation)
  • โšก Performance: Pause processing when scanner is in background
  • ๐ŸŽฎ Control: Programmatic start/stop and torch control
  • ๐Ÿ”ฆ Torch Toggle: controller.toggleTorch() or controller.setTorch(enabled: true)

Automatic Scanning #

// Default: auto-scan after 2 seconds (enabled by default)
MultiQrTrackerView(
  onQrCodeScanned: (value) => print(value),
)

// Custom delay: auto-scan after 5 seconds
MultiQrTrackerView(
  onQrCodeScanned: (value) => print(value),
  autoScanConfig: AutoScanConfig(scanDelay: Duration(seconds: 5)),
)

// Manual only: disable auto-scan (requires button press)
MultiQrTrackerView(
  onQrCodeScanned: (value) => print(value),
  autoScanConfig: AutoScanConfig(enabled: false),
)

Torch (Flashlight) Control #

// Manual control - shows a torch button
MultiQrTrackerView(
  onQrCodeScanned: (value) => print(value),
  torchMode: TorchMode.manual,
)

// Auto mode - turns on in low light
MultiQrTrackerView(
  onQrCodeScanned: (value) => print(value),
  torchMode: TorchMode.auto,
)

// Always off (default)
MultiQrTrackerView(
  onQrCodeScanned: (value) => print(value),
  torchMode: TorchMode.off,
)

// Custom position (topLeft, topRight, bottomLeft, bottomRight)
MultiQrTrackerView(
  onQrCodeScanned: (value) => print(value),
  torchMode: TorchMode.manual,
  torchButtonPosition: TorchButtonPosition.topRight,
)

Advanced Example #

MultiQrTrackerView(
  onQrCodeScanned: (String value) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text('Scanned: $value')),
    );
  },
  
  // Torch control: off, auto, or manual
  torchMode: TorchMode.manual,
  torchButtonPosition: TorchButtonPosition.bottomRight,
  
  // Customize QR code borders
  borderColor: Colors.blue,
  borderWidth: 4.0,
  borderPadding: 12.0,
  cornerRadius: 20.0,
  
  // Customize scan buttons
  scanButtonColor: Colors.green,
  iconColor: Colors.white,
  
  // Optional scan frame with corner indicators
  showScanFrame: true,
  scanFrameColor: Colors.white,
  scanFrameSize: 250.0,
  scanFrameCornerLength: 40.0,
  scanFrameCornerWidth: 4.0,
  
  // Error handling
  onCameraError: (String error) {
    print('Camera error: $error');
  },
  onPermissionDenied: () {
    print('Camera permission denied');
  },
)

๐ŸŽจ Customization #

Parameter Type Default Description
onQrCodeScanned Function(String) required Callback when QR code is scanned
controller MultiQrTrackerController? null Optional controller for programmatic camera control
autoScanConfig AutoScanConfig enabled: true, delay: 2s Auto-scan configuration: enabled flag and delay duration
torchMode TorchMode TorchMode.off Torch control: off, auto, or manual
torchButtonPosition TorchButtonPosition bottomRight Torch button position: topLeft, topRight, bottomLeft, bottomRight
borderColor Color? null Border color: specific color or null for auto-mode
borderWidth double 3.0 Width of border lines
borderPadding double 8.0 Extra padding around QR codes
cornerRadius double 12.0 Border corner radius
scanButtonColor Color Colors.blue Scan button background color
iconColor Color Colors.white Scan button icon color
torchButtonBackgroundColor Color Colors.black54 Torch button background color (manual mode)
torchButtonIconColor Color Colors.white Torch button icon color (manual mode)
showScanFrame bool false Show scan frame with corner indicators
scanFrameColor Color Colors.white Color of scan frame corners
scanFrameSize double 250.0 Size of scan frame (width and height)
scanFrameCornerLength double 40.0 Length of corner lines
scanFrameCornerWidth double 4.0 Thickness of corner lines
onCameraError Function(String)? null Camera error callback
onPermissionDenied VoidCallback? null Permission denied callback

๐Ÿ“Š How It Works #

  1. Automatic Permission Handling: Requests camera permission at runtime when first initialized (both platforms)
  2. Native Camera: Uses CameraX (Android) and AVFoundation (iOS) for camera preview and capture
  3. Detection: ML Kit Barcode Scanning (Android) and AVCaptureMetadataOutput (iOS) detect QR codes in real-time
  4. Auto-Scan Timer: Automatically triggers scanning after configured delay (default 2 seconds)
  5. Coordinate Mapping: Transforms camera coordinates to screen coordinates with BoxFit.cover
  6. Border Rendering: Draws dynamic borders using corner points to match QR code rotation
  7. Adaptive UI: Automatically switches between full button and icon-only based on QR code size
  8. Scan Frame: Optional corner indicators to guide user positioning

๐Ÿ”ง API Reference #

MultiQrTrackerView #

The main widget for QR code detection.

MultiQrTrackerView({
  Key? key,
  required Function(String value) onQrCodeScanned,
  Color? borderColor,
  double borderWidth = 3.0,
  double borderPadding = 8.0,
  double cornerRadius = 12.0,
  Color scanButtonColor = Colors.blue,
  Color iconColor = Colors.white,
  bool showScanFrame = false,
  Color scanFrameColor = Colors.white,
  double scanFrameSize = 250.0,
  double scanFrameCornerLength = 40.0,
  double scanFrameCornerWidth = 4.0,
  Function(String error)? onCameraError,
  VoidCallback? onPermissionDenied,
})

QrCodeInfo #

Model class containing QR code information:

class QrCodeInfo {
  final String value;
  final Rect boundingBox;
  final List<Offset> corners;
  
  Offset get center;
  double get width;
  double get height;
  bool get isLargeEnoughForFullButton;
}

๐Ÿ“– Example App #

Check out the example directory for a complete demo app showing:

  • Multiple QR code detection
  • Real-time orientation switching
  • Dynamic color customization
  • Scan history tracking
  • Error handling

Run the example:

cd example
flutter run

๐Ÿงช Testing #

The package includes comprehensive tests with >90% coverage:

flutter test --coverage

๐Ÿค Contributing #

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

๐Ÿ“ License #

This project is licensed under the MIT License - see the LICENSE file for details.

๐Ÿ’– Support #

If you find this package helpful, please:

๐Ÿ‘จโ€๐Ÿ’ป Author #

Dhia Bechattaoui

๐Ÿ™ Acknowledgments #

  • Built with CameraX for native Android camera integration
  • Built with AVFoundation for native iOS camera integration
  • Uses ML Kit Barcode Scanning for Android QR code detection
  • Uses AVCaptureMetadataOutput for iOS QR code detection
  • Inspired by the need for reliable multi-QR code scanning in Flutter apps

๐Ÿ“ˆ Changelog #

See CHANGELOG.md for a list of changes.

๐Ÿ”ฎ Roadmap #

  • โœ… iOS platform support
  • โฌœ Landscape orientation support
  • โฌœ Auto-rotate support
  • โฌœ Barcode format detection (EAN, Code128, etc.)
  • โœ… Flashlight control (off, auto, manual modes)
  • โฌœ Zoom controls
  • โฌœ Image picker scanning
  • โฌœ Custom overlay widgets

Made with โค๏ธ by Dhia Bechattaoui

2
likes
160
points
263
downloads

Publisher

verified publisherbechattaoui.dev

Weekly Downloads

A Flutter package for detecting and tracking multiple QR codes simultaneously on Android and iOS with adaptive UI overlays. Native CameraX and AVFoundation implementation.

Repository (GitHub)
View/report issues

Topics

#qr-code #qr-scanner #multi-detection #camera #barcode

Documentation

Documentation
API reference

Funding

Consider supporting this project:

github.com

License

MIT (license)

Dependencies

flutter

More

Packages that depend on multi_qr_tracker

Packages that implement multi_qr_tracker